Anton Unt
Anton Unt

Reputation: 1875

Best Datasource Configuration for UITableView with Sections

I have an array

    secInfArr = []
    let secInf1 = SecInfObj.init()
    secInf1.selected = true
    secInf1.itemName = "item1"
    secInf1.sectionName = "section3"
    secInfArr.append(secInf1)

    let secInf2 = SecInfObj.init()
    secInf2.selected = true
    secInf2.itemName = "item1"
    secInf2.sectionName = "section1"
    secInfArr.append(sectionInfo2)

    let secInf3 = SecInfObj.init()
    secInf3.selected = true
    secInf3.itemName = "item1"
    secInf3.sectionName = "section1"
    secInfArr.append(secInf3)

    let secInf4 = SecInfObj.init()
    secInf4.selected = false
    secInf4.itemName = "item1"
    secInf4.sectionName = "section2"
    secInfArr.append(secInf4)

and I want to create a tableView where all of this content is grouped by the sectionName property, and all the itemNames that are in that section are sorted alphabetically.

So far, I am doing what I think is inefficient. I am doing a Distinct operation on the sectionName property in the array, and then using it to name the sections and count them. After that, in the CellForRowAtIndexPath method I just filter the array using the sectionName, and add the cells.

I have also thought of using NSFetchedResultsController but I don't think it will be such a good idea, since the data is not persistent in nature and therefore doesn't need to be in a managedObject form.

What is the ideal way of structuring the data for a grouped table view in this case?

Upvotes: 0

Views: 523

Answers (2)

vadian
vadian

Reputation: 285140

I recommend an object oriented solution for example a struct with a name property and an items array, here in a generic form.

struct Section<T> {

    let name : String
    var items = [T]()

}

If the items array is mutated frequently use a class rather than a struct to take advantage of the reference semantics.

When populating the data source assign the SecInfObj objects to the appropriate Section instance.

The items can be sorted easily, you can declare your data source

var data = [Section<SecInfObj>]()

In numberOfRows return

return data[section].items.count

You get the section by index path with

let section = data[indexPath.section]

and then the items with

let items = section.items[indexPath.row]

Upvotes: 2

xmhafiz
xmhafiz

Reputation: 3538

I would suggest to make them separately into different arrays based on section. It is much easier to be called in datasource especially for numberOfRowsInSection and cellForRowAt methods. It also easy for UITableView to get data for each cells since it access directly to arrays by its index.

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

    if section == 0 {
        return items0.count
    }
    else if section == 1 {
        return items1.count
    }
    return 0
}

or also could be similarly like below. If all are seperately into items[0] ... items [n]

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

    return items[section].count
}

Upvotes: 0

Related Questions