解决方案 SWIFT 4
我能够在 rmaddy 的帮助下使用 UILocalizedIndexedCollation 类找到解决方案。
以下代码代表我的ConctactsVC:
import UIKit
import Contacts
class ContactsVC: UITableViewController {
let cellID = "cellID"
var contacts = [Contact]()
var contactsWithSections = [[Contact]]()
let collation = UILocalizedIndexedCollation.current() // create a locale collation object, by which we can get section index titles of current locale. (locale = local contry/language)
var sectionTitles = [String]()
private func fetchContacts(){
let store = CNContactStore()
store.requestAccess(for: (.contacts)) { (granted, err) in
if let err = err{
print("Failed to request access",err)
return
}
if granted {
print("Access granted")
let keys = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey]
let fetchRequest = CNContactFetchRequest(keysToFetch: keys as [CNKeyDescriptor])
fetchRequest.sortOrder = CNContactSortOrder.userDefault
do {
try store.enumerateContacts(with: fetchRequest, usingBlock: { ( contact, error) -> Void in
guard let phoneNumber = contact.phoneNumbers.first?.value.stringValue else {return}
self.contacts.append(Contact(givenName: contact.givenName, familyName: contact.familyName, mobile: phoneNumber))
})
for index in self.contacts.indices{
print(self.contacts[index].givenName)
print(self.contacts[index].familyName)
print(self.contacts[index].mobile)
}
self.setUpCollation()
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
catch let error as NSError {
print(error.localizedDescription)
}
}else{
print("Access denied")
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(dimissContactsVC))
navigationItem.title = "Contacts"
navigationController?.navigationBar.prefersLargeTitles = true
//Changing section index color
self.tableView.sectionIndexColor = UIColor.red
// need to register a custom cell
tableView.register(ContactsCell.self, forCellReuseIdentifier: cellID)
fetchContacts()
//Test
// let contact1 = Contact(name: "Anuska", mobile: "123434")
//
// let contact2 = Contact(name: "Anuj Sinha", mobile: "2321234")
//
// let contact3 = Contact(name: "Maria", mobile: "343434")
//
// let contact4 = Contact(name: "Jacob", mobile: "34454545")
//
// let contact5 = Contact(name: "Macculam", mobile: "455656")
//
// let contact6 = Contact(name: "Sophia", mobile: "4567890")
//
// self.contacts = [contact1, contact2, contact3, contact4, contact5, contact6]
}
override func viewWillAppear(_ animated: Bool) {
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
@objc func setUpCollation(){
let (arrayContacts, arrayTitles) = collation.partitionObjects(array: self.contacts, collationStringSelector: #selector(getter: Contact.givenName))
self.contactsWithSections = arrayContacts as! [[Contact]]
self.sectionTitles = arrayTitles
print(contactsWithSections.count)
print(sectionTitles.count)
}
@objc func dimissContactsVC(){
dismiss(animated: true, completion: nil)
}
override func numberOfSections(in tableView: UITableView) -> Int {
return sectionTitles.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return contactsWithSections[section].count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//let cell = tableView.dequeueReusableCell(withIdentifier: cellID, for: indexPath) as! ContactsCell
let cell = ContactsCell(style: .subtitle, reuseIdentifier: cellID)
cell.link = self // custom delegation
let contact = contactsWithSections[indexPath.section][indexPath.row]
cell.selectionStyle = .default
cell.textLabel?.text = contact.givenName + " " + contact.familyName
cell.detailTextLabel?.text = contact.mobile
return cell
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sectionTitles[section]
}
//Changing color for the Letters in the section titles
override func tableView(_ tableView: UITableView, willDisplayHeaderView view:UIView, forSection: Int) {
if let headerTitle = view as? UITableViewHeaderFooterView {
headerTitle.textLabel?.textColor = UIColor.red
}
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 44
}
override func sectionIndexTitles(for tableView: UITableView) -> [String]? {
return sectionTitles
}
}
extension UILocalizedIndexedCollation {
//func for partition array in sections
func partitionObjects(array:[AnyObject], collationStringSelector:Selector) -> ([AnyObject], [String]) {
var unsortedSections = [[AnyObject]]()
//1. Create a array to hold the data for each section
for _ in self.sectionTitles {
unsortedSections.append([]) //appending an empty array
}
//2. Put each objects into a section
for item in array {
let index:Int = self.section(for: item, collationStringSelector:collationStringSelector)
unsortedSections[index].append(item)
}
//3. sorting the array of each sections
var sectionTitles = [String]()
var sections = [AnyObject]()
for index in 0 ..< unsortedSections.count { if unsortedSections[index].count > 0 {
sectionTitles.append(self.sectionTitles[index])
sections.append(self.sortedArray(from: unsortedSections[index], collationStringSelector: collationStringSelector) as AnyObject)
}
}
return (sections, sectionTitles)
}
}
我还有一个名为 Contact 的模型文件:
@objc class Contact : NSObject {
@objc var givenName: String!
@objc var familyName: String!
@objc var mobile: String!
init(givenName: String, familyName: String, mobile: String) {
self.givenName = givenName
self.familyName = familyName
self.mobile = mobile
}
}
图片: