【问题标题】:Swift 4.2 Search contacts with Search Bar using Contacts FrameworkSwift 4.2 使用联系人框架通过搜索栏搜索联系人
【发布时间】:2018-09-08 22:23:20
【问题描述】:

我目前正在开发一个联系人应用程序,只是为了测试一些功能,但我被搜索栏卡住了。我无法在主页中的所有联系人之间进行搜索。 Swift 4.2 和 Xcode 10

class ContactsViewController: UITableViewController, CNContactViewControllerDelegate, UISearchBarDelegate {
// Outlet for Search Bar
@IBOutlet weak var searchBar: UISearchBar!

这是我在 IBOutlet 上的代表的定义

然后我的功能是在主页中显示联系人

/ * Show Contacts *
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if contactList != nil {
        return contactList.count
    }
    return 0
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "contactCell", for: indexPath)

    let contact: CNContact!
    contact = contactList[indexPath.row]

    cell.textLabel?.text = "\(contact.givenName) \(contact.familyName)"
    return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let contact = contactList[indexPath.row]
    let controller = CNContactViewController(for: contact)
    navigationController?.pushViewController(controller, animated: true)
}

我如何使用这个 searchBar 来查看我的联系人,并使用 Name 或 Surname 作为键。

这是我的尝试之一,但contains 出现错误:

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    if searchBar.text == nil || searchBar.text == "" {
        inSearchMode = false

        view.endEditing(true)

        tableView.reloadData()
    } else {
        inSearchMode = true

        filteredData = contactList.filter({$0.contains(searchBar.text!)})

        tableView.reloadData()
    }
}

【问题讨论】:

  • 仅供参考 - 您的表视图数据源和委托方法都基于 contactList 但在搜索时您会更新 filteredData。在执行搜索时,您的数据源和委托方法需要基于 filteredData 的结果。
  • 所以我应该用filteredData更改所有contactList引用?
  • 搜索时,是的。
  • @rmaddy 我不知道什么时候应该使用filteredData,什么时候应该使用contactList
  • 搜索时使用filteredData,不使用时使用contactList。

标签: ios swift uisearchbar contacts


【解决方案1】:

您的 contactList 数组包含 CNContact 实例。所以$0 中的filterCNContactcontains 失败,因为 CNContact 没有 contains 方法。

想想如果你有一个单一的CNContact 变量并且你想看看联系人的名字是否包含搜索文本,你需要写什么。

您可能不想要contains,因为您可能想要进行不区分大小写、不区分变音符号的搜索。

下面是一个查看联系人的名字和姓氏属性的示例。根据需要添加其他属性:

filteredData = contactList.filter {
    $0.givenName.range(of: searchBar.text!, options: [.caseInsensitive, .diacriticInsensitive ]) != nil ||
    $0.familyName.range(of: searchBar.text!, options: [.caseInsensitive, .diacriticInsensitive ]) != nil
}

【讨论】:

  • 我已经尝试过类似的事情,但得到:无法将类型“[CNContact]”的值分配给类型“[String]”
  • 听起来你错误地将filteredData 声明为[String] 而不是[CNContact]filteredData 应该与 contactList 具有相同的类型。
  • 谢谢你的工作,现在我被困在 Index out of range on this if: if inSearchMode { text = filteredData[indexPath.row] } else { contact = contactList[indexPath.row] cell.textLabel ?.text = "(contact.givenName) (contact.familyName)" }
  • 基本上我的错误是我无法保存到文本中,因为无法将 CNContact 转换为字符串
  • 您需要在问题下方看到我的评论。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-28
  • 1970-01-01
  • 1970-01-01
  • 2010-10-23
  • 1970-01-01
相关资源
最近更新 更多