Arrays Swift-Tableview未使用搜索查询正确更新
我正在使用带有tableview的搜索栏控制器。我正在提取手机上的联系人以填充tableview。这是我这部分的代码Arrays Swift-Tableview未使用搜索查询正确更新,arrays,swift,xcode,uitableview,uisearchbar,Arrays,Swift,Xcode,Uitableview,Uisearchbar,我正在使用带有tableview的搜索栏控制器。我正在提取手机上的联系人以填充tableview。这是我这部分的代码 func fetchContacts(){ let key = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey] as [CNKeyDescriptor] let request = CNContactFetchRequest(keysToFetch: key)
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中。我还在tableview上添加了multi selection,以便能够选择多个联系人以继续我的应用程序流程
我的问题是当我在搜索栏中搜索联系人时,它总是在我的tableview中给我错误的联系人。它总是在顶部出现相同的名称
现在,如果我打印我的filteredcontact列表,它将返回本应显示但未显示在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.
}
*/
}
class ContactsViewController:UIViewController、UITableViewDelegate、UITableViewDataSource、UISearchBarDelegate{
@IBVAR表格视图:UITableView!
@ibvar搜索栏:UISearchBar!
var contactStore=CNContactStore()
var contacts=[ContractStruct]()
var filteredContacts=[ContractStruct]()
var setSelectedItems:Set=[]
var搜索=false
重写func viewDidLoad(){
super.viewDidLoad()
//加载视图后执行任何其他设置。
tableView.delegate=self
tableView.dataSource=self
searchBar.delegate=self
中的contactStore.requestAccess(用于:。联系人){(成功,错误)
如果成功{
打印(“授权成功”)
}
self.fetchContacts()
}
filteredContacts=触点
}
func tableView(tableView:UITableView,numberofrowsinssection:Int)->Int{
返回filteredContacts.count
}
func tableView(tableView:UITableView,cellForRowAt indexath:indexPath)->UITableViewCell{
let cell=UITableViewCell(样式:。副标题,reuseIdentifier:nil)
如果setSelectedItems.contains(indexPath.row){
cell.accessoryType=.checkmark
}
否则{
cell.accessoryType=.none
}
让contactToDisplay=contacts[indexPath.row]
cell.textLabel?.text=contactToDisplay.givenName
cell.detailTextLabel?.text=contactToDisplay.number
返回单元
}
func tableView(tableView:UITableView,didSelectRowAt indexPath:indexPath){
如果setSelectedItems.contains(indexPath.row){
setSelectedItems.remove(indexPath.row)
}否则{
setSelectedItems.insert(indexPath.row)
}
tableView.reloadRows(位于:[indexPath],带:。无)
打印(setSelectedItems)
}
func searchBar(searchBar:UISearchBar,textDidChange searchText:String){
如果searchBar.text!==“”{
filteredContacts=触点
}否则{
//过滤结果
filteredContacts=contacts.filter{$0.givenName.lowercased().contains(searchBar.text!.lowercased())
}
}
打印(已过滤的内容)
tableView.reloadData()
}
func searchBarCancelButtonClicked(searchBar:UISearchBar){
搜索=假
searchBar.text=“”
tableView.reloadData()
}
func fetchContacts(){
让key=[CNContactGivenNameKey,CNContactFamilyNameKey,CNContactPhoneNumberKey]作为[CNKeyDescriptor]
let request=CNContactFetchRequest(keystefetch:key)
try!contactStore.在中枚举联系人(with:request){(contact,stoppingPointer)
let name=“\(contact.givenName)\(contact.familyName)”
让number=contact.phoneNumbers.first?.value.stringValue
对于contact.PhoneNumber中的numbero{
如果let number=numbero.value为?CNPhoneNumber,
让label=numbero.label{
var contactToAppend=ContractStruct(给定名称:name,编号:number.stringValue)
self.contacts.append(contactToAppend)
}
}
}
tableView.reloadData()
}
/*
//标记:-导航
//在基于故事板的应用程序中,您通常需要在导航之前做一些准备
覆盖功能准备(对于segue:UIStoryboardSegue,发送方:有吗?){
//使用segue.destination获取新的视图控制器。
//将选定对象传递给新的视图控制器。
}
*/
}
只需在tableView委托的cellForRowAt
函数中将联系人[indexPath.row]
替换为filteredContacts[indexPath.row]
因为存储在
filteredContacts
中的过滤结果和tableView
delegate
函数使用filteredContacts
只需将联系人[indexPath.row]
替换为filteredContacts[indexPath.row]
中的cellForRowAt
tableView委托函数
因为你的过滤结果存储在
filteredContacts
中,而你的tableView
delegate
函数使用filteredContacts我必须替换filteredContacts[indexath.row]
中的cellForRowAt
才能工作。我必须替换filteredContacts[indexath.row]
在cellForRowAt
中运行。只需将tableView.reloadData()
移动到contactStore中。在fetchContacts
函数中枚举contacts
的作用域的最后一行。这是一个异步过程,因此如果您查看它,您应该会看到在enumarateContacts
@emrcftci之前调用的重载行,它仍然提供相同的输出。@emrcftci始终会出现名称Kate Bell(来自模拟器的联系人列表)。请尝试将联系人[indexath.row]
替换为筛选器