Как искать телефонные контакты в swift

#swift #search #tableview #contacts

#swift #Поиск #просмотр таблицы #Контакты

Вопрос:

В проекте я получаю все свои контакты.. здесь мне нужно выполнить поиск контактов по их имени, как это сделать

я сделал почти, но не смог отфильтровать textDidChange

ниже приведен мой проверенный код:

 class ContactsViewController1: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var joinersTableView: UITableView!
    var contacts = [CNContact]()

    var search = false
    var searchArray = [CNContact]()

    func numberOfSections(in tableView: UITableView) -> Int {
        return 2
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if section == 0 {
            return jsonArrayTagged.count
        } else {
            if search {
                return searchArray.count
            } else {
                return contacts.count
            }
        }
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if indexPath.section == 1 {
            var cell1: ContactsTableViewCell2 = tableView.dequeueReusableCell(withIdentifier: "ContactsTableViewCell2", for: indexPath) as! ContactsTableViewCell2
            if search {
                cell1.nameLbl.text    = searchArray[indexPath.row].givenName   " "   searchArray[indexPath.row].familyName
                cell1.empRoleLbl.text = searchArray[indexPath.row].phoneNumbers.first?.value.stringValue
                cell1.inviteButn.addTarget(self, action: #selector(connected(sender:)), for: .touchUpInside)
            } else {
                cell1.nameLbl.text    = contacts[indexPath.row].givenName   " "   contacts[indexPath.row].familyName
                cell1.empRoleLbl.text = contacts[indexPath.row].phoneNumbers.first?.value.stringValue
                cell1.inviteButn.addTarget(self, action: #selector(connected(sender:)), for: .touchUpInside)
            }

            return cell1
        }

        return UITableViewCell()
    }
}

extension ContactsViewController: UISearchBarDelegate {
    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        searchArray = contacts.filter({$0.lowercased().prefix(searchText.count) == searchText.lowercased()})
        search = true

        joinersTableView.reloadData()
    }

    func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
        search = false
        searchBar.text = ""
        joinersTableView.reloadData()
    }
}
  

ошибка:

Значение типа ‘CNContact’ не имеет элемента ‘в нижнем регистре’

Ответ №1:

Вы не можете просто использовать a CNContact как a String и сравнивать его с a String . Вам нужно указать, какое String свойство CNContact вы хотите отфильтровать.

Если вы хотите выполнить поиск familyName , например, сделайте $0.familyName.lowerCased() вместо $0.lowerCased , поскольку $0 это a CNContact .

 extension ContactsViewController: UISearchBarDelegate {
    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        searchArray = contacts.filter {$0.familyName.lowercased().prefix(searchText.count) == searchText.lowercased()}
        search = true

        joinersTableView.reloadData()
    }
...
}
  

Не имеет отношения к вашему вопросу, но почему вы ищете только начало текста? Использование localizedCaseInsensitiveContains вместо prefix даст гораздо лучший пользовательский интерфейс.

Ответ №2:

Вам не нужно использовать search: Bool.

Попробуйте этот код:

 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if section == 0 {
        return jsonArrayTagged.count
    } else {
        return searchArray.count
    }
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if indexPath.section == 1 {
        var cell1: ContactsTableViewCell2 = tableView.dequeueReusableCell(withIdentifier: "ContactsTableViewCell2", for: indexPath) as! ContactsTableViewCell2
        cell1.nameLbl.text    = searchArray[indexPath.row].givenName   " "   searchArray[indexPath.row].familyName
        cell1.empRoleLbl.text = searchArray[indexPath.row].phoneNumbers.first?.value.stringValue
        cell1.inviteButn.addTarget(self, action: #selector(connected(sender:)), for: .touchUpInside)
        return cell1
    }

    return UITableViewCell()
}

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    if searchText.isEmpty{
        searchArray = contacts
        joinersTableView.reloadData()
    }else{
        searchArray = contacts.filter({$0.familyName.lowercased().contains(searchText.lowercased()) || $0.middleName.lowercased().contains(searchText.lowercased()) || $0.givenName.lowercased().contains(searchText.lowercased())})
        joinersTableView.reloadData()
    }
}
    
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
    searchBar.text = ""
    searchArray = contacts
    joinersTableView.reloadData()
}
  

Комментарии:

1. спасибо … на самом деле моя панель поиска в viewcontrl1 (означает панель мониторинга) и мои контакты tableview в viewcontroller2… теперь, как я могу выполнить поиск контактов 2ndVC в строке поиска 1stVC…. пожалуйста, помогите

2. Пожалуйста, четко объясните свою идею. 2. контроллеры просмотра в той же сцене или после поиска имени вы нажмете на vc2, чтобы просмотреть список?

3. Я думаю, вам следует выполнить поиск «Как передавать данные с помощью сегмента в Swift».