如何使用自定义模型类按部分按字母顺序对tableView中的数据进行排序?

时间:2017-01-14 04:57:07

标签: swift uitableview sorting swift3

我是编码的新手,并且一直在按字母顺序按部分对我的tableview行中的数据(名称)进行排序。我设法创建了部分和索引,但无法弄清楚如何对名称进行排序;每个部分都有相同的A-Z名称列表。

我有一个具有对象的Names模型类:nameTitle,nameDetail,image,纬度坐标和经度坐标。 tableView显示nameTitle.text。其他对象在另一个视图控制器中显示或访问。

以下是我的TableViewController的示例代码:

import UIKit

class TableOfContentsVC: UIViewController, UITableViewDelegate,  UITableViewDataSource {

@IBAction func backButtonPressed(_ sender: Any) {

    dismiss(animated: false, completion: nil)

}

@IBOutlet weak var tableView: UITableView?

var name = [Name]()

override func viewDidLoad() {
    super.viewDidLoad()

    let cell001 = Name (nameTitle: "Acker" , nameDetail: "Details for Acker are listed here.", picture: UIImage (named: "somePicture.jpg"), latCoordinates: 38, longCoordinates: 119)

    name.append (cell001)

    let cell002 = Name (nameTitle: "Baker" , nameDetail: "Details for Baker are listed here.", picture: UIImage (named: "somePicture.jpg"), latCoordinates: 38, longCoordinates: 119)

    name.append (cell002)

    let cell003 = Name (nameTitle: "Caker" , nameDetail: "Details for Caker are listed here.", picture: UIImage (named: "somePicture.jpg"), latCoordinates: 38, longCoordinates: 119)

    name.append (cell003)

    let cell004 = Name (nameTitle: "Dacker" , nameDetail: "Details for Dacker are listed here.", picture: UIImage (named: "somePicture.jpg"), latCoordinates: 38, longCoordinates: 119)

    name.append (cell004)

    let cell005 = Name (nameTitle: "Ecker" , nameDetail: "Details for Ecker are listed here.", picture: UIImage (named: "somePicture.jpg"), latCoordinates: 38, longCoordinates: 119)

    name.append (cell005)

    let cell006 = Name (nameTitle: "Facker" , nameDetail: "Details for Facker are listed here.", picture: UIImage (named: "somePicture.jpg"), latCoordinates: 38, longCoordinates: 119)

    name.append (cell006)
}
func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int {
    let currentCollation = UILocalizedIndexedCollation.current() as UILocalizedIndexedCollation
    return currentCollation.section(forSectionIndexTitle: index)
}

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    let currentCollation = UILocalizedIndexedCollation.current() as UILocalizedIndexedCollation
    let sectionTitles = currentCollation.sectionTitles as NSArray
    return sectionTitles.object(at: section) as? String

}

func sectionIndexTitles(for tableView: UITableView) -> [String]? {
    let currentCollation = UILocalizedIndexedCollation.current() as UILocalizedIndexedCollation
    return (currentCollation.sectionIndexTitles as NSArray) as? [String]


}

func numberOfSections(in tableView: UITableView) -> Int {
    let currentCollation = UILocalizedIndexedCollation.current() as UILocalizedIndexedCollation
    let sectionTitles = currentCollation.sectionTitles as NSArray
    return sectionTitles.count

}


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    if let cell = tableView.dequeueReusableCell(withIdentifier: "NameCell", for: indexPath) as? NameCell {

        let name = Name [indexPath.row]

        cell.updateUI(name: name)

    return cell


    } else {

        return UITableViewCell()

    }
}


func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

            return name.count


}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    let name = names [indexPath.row]
    performSegue(withIdentifier: "ContentVC", sender: name)

}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if let destination = segue.destination as? ContentVC {

        if let name = sender as? Name {
            destination.name = name
        }
    }
}  
}

除了让名字按字母顺序显示在相应部分之外,一切都很有效。我尝试了10种不同的方法来实现这一点,没有任何帮助。任何建议将不胜感激。提前谢谢!

1 个答案:

答案 0 :(得分:10)

你这样做是错误的。您没有使用数据来生成索引。

我们假设您拥有一系列数据var name: [Name]

  1. 定义每个Name所属的部分:
  2. extension Name {
        var titleFirstLetter: String {
            return String(self.nameTitle[self.nameTitle.startIndex]).uppercased()
        }
    }
    
    1. 从您的数据生成索引
    2. // 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. 生成部分
      2. 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. 使用它们
        2. 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]
              ...
          }
          

          编辑 - 完整示例:

          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
              }
          }
          

          example screenshot