Лучшим подходом было бы иметь 2 источника данных, один для нормального состояния, другой при активном поиске, например:
class SearchViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
private var dataSource = [User]() {
didSet {
self.tableview.reloadData()
}
}
private var searchDataSource: [User]? {
didSet {
self.tableView.reloadData()
}
}
override func viewDidLoad() {
super.viewDidLoad()
...
self.searchBtn.delegate = self
}
// some changes to UITableView DataSource/Delegate
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.searchDataSource?.count ?? self.dataSource.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
...
let user = self.searchDataSource?[indexPath.row] ?? self.dataSource[indexPath.row]
...
}
}
Наконец, используйте следующее расширение, расширяющее UISearchBarDelegate
extension SearchViewController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchText.isEmpty {
self.searchDataSource = nil
} else {
self.searchDataSource = self.dataSource.filter({
let fullName = $0.firstName + " " + $0.lastName
return fullName.range(of: searchText, options: [.anchored, .caseInsensitive]) != nil
})
}
}
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
if self.searchDataSource != nil && searchBar.text?.isEmpty ?? true {
self.searchDataSource = nil
}
}
}
, что дает