I\'m new to coding and have been trying to sort the data (names) in my tableview rows alphabetically by section. I\'ve managed to create the sections and an index, but can\'t f
You are doing it the wrong way. You are not using your data to generate your index.
Let's consider you have an array of your data var name: [Name]
Name
belongs:extension Name {
var titleFirstLetter: String {
return String(self.nameTitle[self.nameTitle.startIndex]).uppercased()
}
}
// all the first letters in your data
let firstLetters = names.map { $0.titleFirstLetter }
// some letters appear multiple times, let's remove duplicates
let uniqueFirstLetters = Array(Set(firstLetters))
// sort them
// this is your index
let sortedFirstLetters = uniqueFirstLetters.sorted()
let sections: [[Name]] = sortedFirstLetters.map { firstLetter in
return names
.filter { $0.titleFirstLetter == firstLetter } // only names with the same first letter in title
.sorted { $0.nameTitle < $1.nameTitle } // sort them
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sortedFirstLetters[section]
}
func sectionIndexTitles(for tableView: UITableView) -> [String]? {
return sortedFirstLetters
}
func numberOfSections(in tableView: UITableView) -> Int {
return sections.count // or sortedFirstLetters.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sections[section].count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let name = sections[indexPath.section][indexPath.row]
...
}
Edit - complete example:
class Name {
let nameTitle: String
let nameDetail: String
init(nameTitle: String, nameDetail: String) {
self.nameTitle = nameTitle
self.nameDetail = nameDetail
}
var titleFirstLetter: String {
return String(self.nameTitle[self.nameTitle.startIndex]).uppercased()
}
}
class ViewController : UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView?
var names: [Name] = []
var sortedFirstLetters: [String] = []
var sections: [[Name]] = [[]]
override func viewDidLoad() {
super.viewDidLoad()
let cell001 = Name(nameTitle: "Acker", nameDetail: "Details for Acker are listed here.")
names.append (cell001)
let cell002 = Name(nameTitle: "Baker", nameDetail: "Details for Baker are listed here.")
names.append (cell002)
let cell003 = Name(nameTitle: "Caker" , nameDetail: "Details for Caker are listed here.")
names.append (cell003)
let cell004 = Name(nameTitle: "Dacker", nameDetail: "Details for Dacker are listed here.")
names.append (cell004)
let cell005 = Name(nameTitle: "Ecker", nameDetail: "Details for Ecker are listed here.")
names.append (cell005)
let cell006 = Name(nameTitle: "Facker", nameDetail: "Details for Facker are listed here.")
names.append (cell006)
let firstLetters = names.map { $0.titleFirstLetter }
let uniqueFirstLetters = Array(Set(firstLetters))
sortedFirstLetters = uniqueFirstLetters.sorted()
sections = sortedFirstLetters.map { firstLetter in
return names
.filter { $0.titleFirstLetter == firstLetter }
.sorted { $0.nameTitle < $1.nameTitle }
}
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sortedFirstLetters[section]
}
func sectionIndexTitles(for tableView: UITableView) -> [String]? {
return sortedFirstLetters
}
func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sections[section].count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let name = sections[indexPath.section][indexPath.row]
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: nil)
cell.textLabel?.text = name.nameTitle
cell.detailTextLabel?.text = name.nameDetail
return cell
}
}