How do you sort data in a tableView alphabetically by section using a custom model class?

前端 未结 1 1278
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-02-03 15:28

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

相关标签:
1条回答
  • 2021-02-03 16:32

    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]

    1. Define the section into which every Name belongs:
    extension Name {
        var titleFirstLetter: String {
            return String(self.nameTitle[self.nameTitle.startIndex]).uppercased()
        }
    }
    
    1. Generate the index from your data
    // 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()
    
    1. Generate sections
    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
    }
    
    1. Use 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
        }
    }
    

    0 讨论(0)
提交回复
热议问题