I would change the way you store your contacts using a dictator with the initial letters as keys and put the names corresponding to this initial letter in a subarray:
contacts = ["A": ["Anton", "Anna"], "C": ["Caesar"]]
I simplified the contact path here (in the form of strings), but you got the concept.
I would also store the letter section number in a separate array as follows:
letters = ["A", "C"]
Keep the array sorted and organized, so check after each insert / delete / update. This is not part of the implementation of the table view. I would make Viewcontroller a phone book delegate, so that you can run a method similar to updating from the phone book to update the table.
How to get data for a data source:
number of sections:
letters.count
section heading for section with index i equals
letters[i]
the number of cells in section i equals
contacts[letters[i]].count
and the content for a specific cell c in section i:
contacts[letters[i]][c]
Feel free to ask additional questions if something else is not clear.
UPDATE - How to generate arrays:
I don't need data to sort, if you have already sorted it, you can delete the sort lines below ...
let data = ["Anton", "Anna", "John", "Caesar"] // Example data, use your phonebook data here. // Build letters array: var letters: [Character] letters = data.map { (name) -> Character in return name[name.startIndex] } letters = letters.sort() letters = letters.reduce([], combine: { (list, name) -> [Character] in if !list.contains(name) { return list + [name] } return list }) // Build contacts array: var contacts = [Character: [String]]() for entry in data { if contacts[entry[entry.startIndex]] == nil { contacts[entry[entry.startIndex]] = [String]() } contacts[entry[entry.startIndex]]!.append(entry) } for (letter, list) in contacts { list.sort() }
For Swift 3 :
let data = ["Anton", "Anna", "John", "Caesar"] // Example data, use your phonebook data here. // Build letters array: var letters: [Character] letters = data.map { (name) -> Character in return name[name.startIndex] } letters = letters.sorted() letters = letters.reduce([], { (list, name) -> [Character] in if !list.contains(name) { return list + [name] } return list }) // Build contacts array: var contacts = [Character: [String]]() for entry in data { if contacts[entry[entry.startIndex]] == nil { contacts[entry[entry.startIndex]] = [String]() } contacts[entry[entry.startIndex]]!.append(entry) } for (letter, list) in contacts { contacts[letter] = list.sorted() }
I ran the code on the playground and got the following outputs for
letters:
["A", "C", "J"]
contacts:
["J": ["John"], "C": ["Caesar"], "A": ["Anton", "Anna"]]