Swift - Tableview не обновляется должным образом с помощью поисковых запросов - PullRequest
1 голос
/ 10 апреля 2020

Я использую контроллер панели поиска с таблицей. Я выбираю контакты на моем телефоне, чтобы заполнить таблицу. Вот мой код для этой части.

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()
}

Он правильно получает контакт с разными номерами телефонов и затем отображается в виде таблицы. Я также добавил множественный выбор в табличном представлении, чтобы иметь возможность выбрать несколько контактов, чтобы продолжить просмотр моего приложения.

Моя проблема в том, что когда я ищу контакт в строке поиска, он всегда дает мне неправильные контакты в моей таблице. Это приходит с тем же именем всегда наверху. Возвращает неправильный контакт

Теперь, если я распечатаю свой отфильтрованный список контактов, он возвращает правильный контакт, который должен был отображаться, но не отображаться в виде таблицы. Вот мой код для поиска

    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.
    }
    */

}

Ответы [ 2 ]

0 голосов
/ 10 апреля 2020

Мне пришлось заменить filteredContacts[indexPath.row] в cellForRowAt, чтобы он заработал.

0 голосов
/ 10 апреля 2020

Просто замените contacts[indexPath.row] на filteredContacts[indexPath.row] в cellForRowAt функции делегата tableView.

Поскольку ваши отфильтрованные результаты, сохраненные в filteredContacts, и ваши tableView delegate функции используют filteredContacts

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...