Reputation: 1875
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 itemName
s 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
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
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