I am using NSFetchedResultsController
to populate a tableView. The tableView can get quite long because it shows a list of people, and I want to sort it alphabetically. I know I need to use titleForHeaderInSection
, but I am stuck on how to get the first letter of each object in my fetchedObjectsController.fetchedObjects
and display that as the section header as well as sort it, just how the Contacts app works.
This is what my View Controller looks like.
var fetchedResultsController: NSFetchedResultsController<Client> = {
let fetchRequest: NSFetchRequest<Client> = Client.fetchRequest()
let sortDescriptors = [NSSortDescriptor(key: "name", ascending: false)]
fetchRequest.sortDescriptors = sortDescriptors
return NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: CoreDataStack.context, sectionNameKeyPath: "name", cacheName: nil)
}()
override func numberOfSections(in tableView: UITableView) -> Int {
guard let sections = fetchedResultsController.sections else { return 0 }
return sections.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard let sections = fetchedResultsController.sections else { return 0 }
return sections[section].numberOfObjects
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "clientCell", for: indexPath)
let client = fetchedResultsController.object(at: indexPath)
cell.textLabel?.text = client.name
return cell
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
let client = fetchedResultsController.object(at: indexPath)
ClientController.sharedController.delete(client)
}
}
This is a very small example of how you can get your headers texts, I use a class only for test that have only name, then applying map
using characters.prefix
we get the first characters of the names and after casting to String
and sorting we have what you need
var arrayOfUsers : [User] = [User(name:"test"),User(name:"pest"),User(name:"aest"),User(name:"nest"),User(name:"best")]
let finalArray = arrayOfUsers.map({String.init($0.name.characters.prefix(1)) }).sorted(by: {$0 < $1})
debugPrint(finalArray)
Console log result
["a", "b", "n", "p", "t"]
Hope this helps you