arrays - Swift - Tableview 无法通过搜索查询正确更新
问题描述
我正在使用带有表格视图的搜索栏控制器。我正在获取手机上的联系人以填充表格视图。这是我这部分的代码。
func fetchContacts(){
let key = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey] as [CNKeyDescriptor]
let request = CNContactFetchRequest(keysToFetch: key)
try! contactStore.enumerateContacts(with: request) {(contact, stoppingPointer) in
let name = "\(contact.givenName) \(contact.familyName)"
let number = contact.phoneNumbers.first?.value.stringValue
for numbero in contact.phoneNumbers {
if let number = numbero.value as? CNPhoneNumber,
let label = numbero.label {
var contactToAppend = ContractStruct(givenName: name, number: number.stringValue)
self.contacts.append(contactToAppend)
}
}
}
tableView.reloadData()
}
它正确检索具有不同电话号码的联系人,然后显示在表格视图中。我还在表格视图上添加了多项选择,以便能够选择多个联系人以继续我的应用程序流程。
我的问题是当我在搜索栏中搜索联系人时,它总是在我的表格视图中给我错误的联系人。它总是在顶部出现相同的名称。返回错误的联系方式
现在,如果我打印我的过滤联系人列表,它会返回应该显示但未显示在 tableview 上的正确联系人。这是我的搜索代码
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchBar.text! == "" {
filteredContacts = contacts
} else {
// Filter the results
filteredContacts = contacts.filter { $0.givenName.lowercased().contains(searchBar.text!.lowercased())
}
}
print(filteredContacts)
tableView.reloadData()
}
这是我的完整课程:
class ContactsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate {
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var searchBar: UISearchBar!
var contactStore = CNContactStore()
var contacts = [ContractStruct]()
var filteredContacts = [ContractStruct]()
var setSelectedItems: Set<Int> = []
var searching = false
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
tableView.delegate = self
tableView.dataSource = self
searchBar.delegate = self
contactStore.requestAccess(for: .contacts) {(success, error) in
if success {
print("Authorisation Successful")
}
self.fetchContacts()
}
filteredContacts = contacts
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return filteredContacts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: nil)
if setSelectedItems.contains(indexPath.row) {
cell.accessoryType = .checkmark
}
else {
cell.accessoryType = .none
}
let contactToDisplay = contacts[indexPath.row]
cell.textLabel?.text = contactToDisplay.givenName
cell.detailTextLabel?.text = contactToDisplay.number
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if setSelectedItems.contains(indexPath.row) {
setSelectedItems.remove(indexPath.row)
} else {
setSelectedItems.insert(indexPath.row)
}
tableView.reloadRows(at: [indexPath], with: .none)
print(setSelectedItems)
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchBar.text! == "" {
filteredContacts = contacts
} else {
// Filter the results
filteredContacts = contacts.filter { $0.givenName.lowercased().contains(searchBar.text!.lowercased())
}
}
print(filteredContacts)
tableView.reloadData()
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searching = false
searchBar.text = ""
tableView.reloadData()
}
func fetchContacts(){
let key = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey] as [CNKeyDescriptor]
let request = CNContactFetchRequest(keysToFetch: key)
try! contactStore.enumerateContacts(with: request) {(contact, stoppingPointer) in
let name = "\(contact.givenName) \(contact.familyName)"
let number = contact.phoneNumbers.first?.value.stringValue
for numbero in contact.phoneNumbers {
if let number = numbero.value as? CNPhoneNumber,
let label = numbero.label {
var contactToAppend = ContractStruct(givenName: name, number: number.stringValue)
self.contacts.append(contactToAppend)
}
}
}
tableView.reloadData()
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
解决方案
只需在tableView 委托的功能中替换contacts[indexPath.row]
为。filteredContacts[indexPath.row]
cellForRowAt
因为您存储的过滤结果filteredContacts
和您的tableView
delegate
函数使用filteredContacts
推荐阅读
- java - a.charAt(i) 是如何越界的?什么不见了?
- database - PostgreSQL 中表数的 O(n) 操作是什么?
- c# - 将字符串拆分为临时表时,从临时表中搜索的存储过程不起作用
- javascript - 在反应虚拟化表(多网格)上手动设置滚动量
- java - 如何检查数字是否高于 Java 中的 Integer.MAX_VALUE,当添加一些其他数字时?
- mongodb - 多个查找结果处理
- java - _InternalLinkedHashMap
不是类型转换中自定义类的子类型。从 Firestore 中检索地图数组 - c - 我的编码器程序不打印翻译的消息,在 C
- javascript - 页面加载时触发单选按钮更改
- r - 给出 runif() 最大值和最小值,它们是具有多个条目的小标题