之前項目里有根據地名分組點擊跳轉的需求,就跟通訊錄差不多。在百度到一些他人的成果后找到了通過原生的 UILocalizedIndexedCollation 實現的方式。代碼如下:
class Person: NSObject {
@objc var name: String?
}
class ViewController: UITableViewController {
/// 數據源
private var dataArray = [[Person]]()
/// 每個 section 的標題
private var sectionTitleArray = [String]()
private var indexedCollation = UILocalizedIndexedCollation.current()
override func viewDidLoad() {
super.viewDidLoad()
let nameArray = ["趙", "錢", "孫", "李", "周", "孫", "李", "周", "孫", "李", "周", "吳", "鄭", "王", "郭", "松", "宋", "長", "大", "小"]
var personArray = [Person]()
for name in nameArray {
let p = Person()
p.name = name
personArray.append(p)
}
// 獲得索引數, 這里是27個(26個字母和1個#)
let indexCount = indexedCollation.sectionTitles.count
// 每一個一維數組可能有多個數據要添加,所以只能先創(chuàng)建一維數組,到時直接取來用
for _ in 0..<indexCount {
let array = [Person]()
dataArray.append(array)
}
// 將數據進行分類,存儲到對應數組中
for person in personArray {
// 根據 person 的 name 判斷應該放入哪個數組里
// 返回值就是在 indexedCollation.sectionTitles 里對應的下標
let sectionNumber = indexedCollation.section(for: person, collationStringSelector: #selector(getter: Person.name))
// 添加到對應一維數組中
dataArray[sectionNumber].append(person)
}
// 對每個已經分類的一維數組里的數據進行排序,如果僅僅只是分類可以不用這步
for i in 0..<indexCount {
// 排序結果數組
let sortedPersonArray = indexedCollation.sortedArray(from: dataArray[i], collationStringSelector: #selector(getter: Person.name))
// 替換原來數組
dataArray[i] = sortedPersonArray as! [Person]
}
// 用來保存沒有數據的一維數組的下標
var tempArray = [Int]()
for (i, array) in dataArray.enumerated() {
if array.count == 0 {
tempArray.append(i)
} else {
// 給標題數組添加數據
sectionTitleArray.append(indexedCollation.sectionTitles[i])
}
}
// 刪除沒有數據的數組
for i in tempArray.reversed() {
dataArray.remove(at: i)
}
}
override func numberOfSections(in tableView: UITableView) -> Int {
return sectionTitleArray.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataArray[section].count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let id = "cell"
var cell = tableView.dequeueReusableCell(withIdentifier: id)
if cell == nil {
cell = UITableViewCell(style: .default, reuseIdentifier: id)
}
cell?.textLabel?.text = dataArray[indexPath.section][indexPath.row].name
return cell!
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sectionTitleArray[section]
}
/// 這是右側可以點擊跳轉的控件 title
override func sectionIndexTitles(for tableView: UITableView) -> [String]? {
return sectionTitleArray
}
}
項目地址:https://github.com/yljbyj/UILocalizedIndexedCollation.git
參考文章: