Adding sections, separated by dates, to UITableView in Swift

maxpetter picture maxpetter · Oct 27, 2014 · Viewed 36.5k times · Source

I'm a complete rookie at Swift and iOS programming so you'll have to forgive the perhaps simple question.

I've created a tableView which displays the contents of an array (strings) at the press of a button. Now, I'd like to "group" these strings in tableView sections, sorted by date.

In more detail: When the user taps the button, the string should be inserted at index 0 of the array and be displayed in a section with a header of todays date. If there's values older than today's date in the array, these should be displayed in a separate section for that date. Each section should correspond to a 24 hour day and display all the strings added during that day.

Here's some sample code of what I've achieved so far:

var testArray[String]()
var sectionsInTable[String]()

@IBOutlet weak var testTable: UITableView!

@IBAction func saveButton(sender: AnyObject) {

testArray.insert("\(strTest)", atIndex: 0)
testTable.reloaddata()

}

func numberOfSectionsInTableView(tableView: UITableView) -> Int {

    return sectionsInTable.count

}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{

    return testArray.count

}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    var cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")

    cell.textLabel.text = String(testArray[indexPath.row])        

    return cell
}

I really don't know how to manage the sections part. Hopefully someone can point me in the right direction. Thanks!

Answer

Adam Bardon picture Adam Bardon · Apr 20, 2015

I was in need for something similar, and while Ron Fessler's solution works, when there's a lot of sections/rows, it took a very long time for table to load data, and even after that it wasn't much responsive. Main issue there I think is getSectionItems function as it will always go through all of items...

My solution:

struct TableItem {
    let title: String
    let creationDate: NSDate
}

var sections = Dictionary<String, Array<TableItem>>()
var sortedSections = [String]()

@IBAction func saveButton(sender: AnyObject) {

    let date:String = "your date in string..."

    //if we don't have section for particular date, create new one, otherwise we'll just add item to existing section
    if self.sections.indexForKey(date) == nil {
        self.sections[date] = [TableItem(title: name, creationDate: date)]
    }
    else {
        self.sections[date]!.append(TableItem(title: name, creationDate: date))
    } 

    //we are storing our sections in dictionary, so we need to sort it 
    self.sortedSections = self.sections.keys.array.sorted(>)
    self.tableView.reloadData()
}

tableView dataSource methods:

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return sections.count
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return sections[sortedSections[section]]!.count
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    var cell = tableView.dequeueReusableCellWithIdentifier("Cell")        

    let tableSection = sections[sortedSections[indexPath.section]]
    let tableItem = tableSection![indexPath.row]

    cell.titleLabel?.text = tableItem.title

    return cell
}

override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return sortedSections[section]
}