I have a list of names sorted alphabetically, and now I want display these names in a table view. I'm struggling with grouping these names for each letter.
My code looks like this:
let sections:Array<AnyObject> = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"] var usernames = [String]() func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{ let cellID = "cell" let cell: UITableViewCell = self.tv.dequeueReusableCellWithIdentifier(cellID) as UITableViewCell cell.textLabel?.text = usernames[indexPath.row] return cell } func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{ return usernames.count } func numberOfSectionsInTableView(tableView: UITableView) -> Int{ return 26 } func sectionIndexTitlesForTableView(tableView: UITableView) -> [AnyObject]!{ return self.sections } func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int{ return index } func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String?{ return self.sections[section] as? String }
and it all works pretty good except for the grouping which makes my table view end up like this:
So I know you should be able to use the filtered function in an Array, but I did not understand how to implement it.
Any suggestions on how to proceed would be appreciated.
Overview. A table view displays a single column of vertically scrolling content, divided into rows and sections. Each row of a table displays a single piece of information related to your app. Sections let you group related rows together.
You cannot change the table style once it's initialised. You'd have to create a new UITableView instance with a different style.
In Swift 4 Dictionary(grouping:by:) was introduced to group a sequence to a dictionary by an arbitrary predicate.
This example maps the grouped dictionary to a custom struct Section
struct Section { let letter : String let names : [String] } ... let usernames = ["John", "Nancy", "James", "Jenna", "Sue", "Eric", "Sam"] var sections = [Section]() override func viewDidLoad() { super.viewDidLoad() // group the array to ["N": ["Nancy"], "S": ["Sue", "Sam"], "J": ["John", "James", "Jenna"], "E": ["Eric"]] let groupedDictionary = Dictionary(grouping: usernames, by: {String($0.prefix(1))}) // get the keys and sort them let keys = groupedDictionary.keys.sorted() // map the sorted keys to a struct sections = keys.map{ Section(letter: $0, names: groupedDictionary[$0]!.sorted()) } self.tableView.reloadData() } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cellID = "cell" let cell = tableView.dequeueReusableCell(withIdentifier: cellID, for: indexPath) let section = sections[indexPath.section] let username = section.names[indexPath.row] cell.textLabel?.text = username return cell } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return sections[section].names.count } func numberOfSections(in tableView: UITableView) -> Int { return sections.count } func sectionIndexTitles(for tableView: UITableView) -> [String]? { return sections.map{$0.letter} } func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { return sections[section].letter }
This is how I recently implemented sorted list in a tableView in Swift programmatically,
import UIKit class BreedController: UITableViewController{ var breeds = ["A": ["Affenpoo", "Affenpug", "Affenshire", "Affenwich", "Afghan Collie", "Afghan Hound"], "B": ["Bagle Hound", "Boxer"]] struct Objects { var sectionName : String! var sectionObjects : [String]! } var objectArray = [Objects]() override func viewDidLoad() { super.viewDidLoad() tableView.delegate = self tableView.dataSource = self tableView.registerClass(UITableViewCell.classForCoder(), forCellReuseIdentifier: "Cell") // SORTING [SINCE A DICTIONARY IS AN UNSORTED LIST] var sortedBreeds = sorted(breeds) { $0.0 < $1.0 } for (key, value) in sortedBreeds { println("\(key) -> \(value)") objectArray.append(Objects(sectionName: key, sectionObjects: value)) } } override func numberOfSectionsInTableView(tableView: UITableView) -> Int { return objectArray.count } override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return objectArray[section].sectionObjects.count } override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell // SETTING UP YOUR CELL cell.textLabel?.text = objectArray[indexPath.section].sectionObjects[indexPath.row] return cell } override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? { return objectArray[section].sectionName } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With