Reputation: 2924
I have those two structs in swift
struct Objects {
var sectionName: String!
var sectionObjects: [Brands]!
}
struct Brands {
var id: String!
var name: String!
}
And those three empty arrays
lazy var sortedLetters = [String]()
lazy var sortedBrands = [Brands]()
lazy var objectBrands = [Objects]()
The sortedLetters array is for making the headers in the tableview.
The sortedBrands is an array of brands, in which i'm trying to populate the brand's name if the letter is the same as the sortedLetters array.
The objectBrands is an array of objects in which as you will see in the tableview functions, i get the data of Brands and the header's letter.
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return requests.objectBrands[section].sectionName
}
func numberOfSections(in tableView: UITableView) -> Int {
return objectBrands.count
}
func sectionIndexTitles(for tableView: UITableView) -> [String]? {
return sortedLetters
}
func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
let header = view as! UITableViewHeaderFooterView
header.textLabel?.font = UIFont(name: "Helvetica", size: 11)
header.textLabel?.textColor = .black
header.contentView.backgroundColor = .darkGray
}
func tableView(_ tableView: UITableView,
heightForRowAt indexPath: IndexPath) -> CGFloat {
return 70
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return requests.objectBrands[section].sectionObjects.count
}
And in this for loop
I'm trying to append brands inside eacher letter of the array sortedLetters
.
for startNames in self.sortedLetters {
self.objectBrands.append(Objects(sectionName: startNames, sectionObjects: self.sortedBrands))
}
Although it appends ALL Brands. And inside my table view i have something like this
Header : "A"
Cells : All brands
Header : "B"
Cells : All brands
Which is normal cause i'm missing something in my for loop.
How can i change my for loop
in swift syntax, so it can append for example in letter "A" each brand name which starts with "A" ?
So it will show something like this
Header : "A"
Cells : Brands that start with A
Header : "B"
Cells : Brands that start with B
etc...
Thanks a lot!
Upvotes: 0
Views: 1061
Reputation: 16327
Use a dictionary for your sections where the key is the letter for the section heading and the value is an array containing your models for that section. You will need to separately sort your keys (or simply precompute and store your sortedKeys in an array; you need to do this every time the data changes if you want a sparse dictionary (i.e. you only show headers for sections with items, or just once if you want to show all the headers irrespective of whether or not they are empty).
var sections: [String: [ModelType]] = [:]
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sortedSectionKeys[section] // sortedSectionKeys = sections.keys.sorted {$0.0 < $0.1}
}
func numberOfSections(in tableView: UITableView) -> Int {
return sections.keys.count
}
func sectionIndexTitles(for tableView: UITableView) -> [String]? {
return sortedSectionKeys
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sections[sortedSectionKeys[section]]?.count ?? 0
}
Upvotes: 1
Reputation: 5523
You can filter your sortedLetters
array by first letter like this:
sortedLetters.filter({ $0.substring(to: $0.index($0.startIndex, offsetBy: 1)).lowercased() == "a" })
This will show only brands that being with "a" (lower case or upper case), for example. You can replace that "a" with whichever variable you're using to determine which section you're in.
Upvotes: 1
Reputation: 3593
// Iterate each Header Name
for startNames in self.sortedLetters {
// Filter out the brands which name starts with startNames
// Here, I also sorted the brand by its name.
let brands = self.sortedBrands.filter() {$0.name.hasPrefix(startNames)}.sorted(by: {$0.name < $1.name})
self.objectBrands.append(Objects(sectionName: startNames, sectionObjects:brands))
}
Upvotes: 2