#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».