Arrays Swift-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)

我正在使用带有tableview的搜索栏控制器。我正在提取手机上的联系人以填充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中。我还在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]
替换为
筛选器