Alphabetical sections in table table view in swift
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 UIKitclass 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 }}
Download CountryList Json file and put in side your project
https://gist.github.com/keeguon/2310008
var json = NSArray() var arr_name = NSArray() var arrIndexSection : NSArray = ["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"]override func viewDidLoad() { let path = Bundle.main.path(forResource: "countries", ofType: "json") let data = NSData(contentsOfFile: path! ) json = (try! JSONSerialization.jsonObject(with: data as! Data, options: JSONSerialization.ReadingOptions.mutableContainers)) as! NSArray arr_name = json.value(forKey: "name") as! NSArray; tableview.reloadData() super.viewDidLoad()}// Side List in tableviewpublic func numberOfSections(in tableView: UITableView) -> Int { return 26}public func sectionIndexTitles(for tableView: UITableView) -> [String]? { return self.arrIndexSection as? [String] //Side Section title}public func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int{ return index}public func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { return arrIndexSection.object(at: section) as? String}// number of rows in table viewpublic func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{ let predicate = NSPredicate(format: "SELF beginswith[c] %@", arrIndexSection.object(at: section) as! CVarArg) let arrContacts = (arr_name as NSArray).filtered(using: predicate) return arrContacts.count;}public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{ let cell : TableViewCell=self.tableview.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell let predicate = NSPredicate(format: "SELF beginswith[c] %@", arrIndexSection.object(at: indexPath.section) as! CVarArg) let arrContacts = (arr_name as NSArray).filtered(using: predicate) as NSArray cell.textLabel?.text = arrContacts.object(at: indexPath.row) as? String return cell}