首页 > 解决方案 > 使用 UILocalizedIndexedCollat​​ion 在 Swift 中创建节索引时,是否有匹配 CNContactSortOrder.userDefault 的选择器?

问题描述

我正在尝试构建一个以 iPhone 的联系人应用程序为模型的应用程序。当我从 CNContactStore 获取记录时。我可以指定 CNContactSortOrder.userDefault。

let fetchRequest = CNContactFetchRequest(keysToFetch:
            [CNContactFormatter.descriptorForRequiredKeys(for: .fullName)])
fetchRequest.sortOrder = CNContactSortOrder.userDefault

我想在创建节索引时复制这种排序顺序。我可以为 CNContact.familyName 创建一个选择器。我需要 .userDefault 之类的东西,因为它会在 familyName 为 nil 时获取其他字段(例如昵称)并将其正确包含在排序结果中。

import UIKit
import Contacts

class SectionIndexesTableViewController: UITableViewController {

    let collation = UILocalizedIndexedCollation.current()
    var sections: [[CNContact]] = []
    var sectionTitles: [String] = []
    var contacts: [CNContact] = [] {
        didSet {
            sectionTitles.removeAll()
            sections.removeAll()
//            let selector: Selector = #selector(getter: CNContact.familyName)
            let selector: Selector = #selector(getter:       CNContact.comparator(forNameSortOrder: .userDefault))
            var sectionsAll = Array(repeating: [], count: collation.sectionTitles.count)
            let sortedContacts = collation.sortedArray(from: contacts, collationStringSelector: selector)
            for contact in sortedContacts {
                let sectionNumber = collation.section(for: contact, collationStringSelector: selector)
                sectionsAll[sectionNumber].append(contact as! CNContact)
            }
            for index in 0 ..< sectionsAll.count {
                if sectionsAll[index].count > 0 {
                    sectionTitles.append(collation.sectionTitles[index])
                    sections.append(sectionsAll[index] as! [CNContact])
                }
            }
            self.tableView.reloadData()
        }
    }


    override func viewDidLoad() {
        super.viewDidLoad()
        let fetchRequest = CNContactFetchRequest(keysToFetch:
            [CNContactFormatter.descriptorForRequiredKeys(for: .fullName)])
        fetchRequest.sortOrder = CNContactSortOrder.userDefault
        let store = CNContactStore()
        do {
            try store.enumerateContacts(with: fetchRequest, usingBlock: { (contact, stop) -> Void in
            self.contacts.append(contact)
            })
        }
        catch let error as NSError {
            print(error.localizedDescription)
        }
    }

    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        return sections.count
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return sections[section].count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "TVCellSectionIndexes", for: indexPath)
        let contact = sections[indexPath.section][indexPath.row]
        let formatter = CNContactFormatter()
        cell.textLabel?.text = formatter.string(from: contact)
        return cell
    }

    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return sectionTitles[section]
    }

    override func sectionIndexTitles(for tableView: UITableView) -> [String]? {
        return collation.sectionIndexTitles
    }

    override func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int {
        return collation.section(forSectionIndexTitle: index)     
    } 
}

我收到的编译错误是:“#selector”的参数不引用“@objc”方法、属性或初始化程序

如何将 .userDefault 公开给 @objc?

Apple 的联系人应用程序添加了记录

标签: iosswift

解决方案


推荐阅读