I think that the issue is that you are tracking whether you are searching or not yourself and manipulating the source data array.
I have an example playground snippet I have used for some other answers which shows you how to do this more efficiently and has some handy helper functions to make it easier.
I think the key parts of this that would be beneficial to you are:
keep a seperate array just of search results, only used when search is active
var filteredNames = [String]()
Make sure that you adjust the count and rows used when searching or not
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if isFiltering() {
return filteredNames.count
} else {
return names.count
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell() // don't do this, i am for example.
var name: String
if isFiltering() {
name = filteredNames[indexPath.row]
} else {
name = names[indexPath.row]
}
cell.textLabel?.text = name
return cell
}
You can use the following helper functions to help you out.
func searchBarIsEmpty() -> Bool {
// Returns true if the text is empty or nil
return searchController.searchBar.text?.isEmpty ?? true
}
func isFiltering() -> Bool {
return searchController.isActive && !searchBarIsEmpty()
}
Full UISearchController Example (playground)
import UIKit
import PlaygroundSupport
class ViewController: UITableViewController {
let searchController = UISearchController(searchResultsController: nil)
var names = [
"John",
"Terry",
"Martin",
"Steven",
"Michael",
"Thomas",
"Jason",
"Matthew"
]
var filteredNames = [String]()
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Search Example"
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Search"
navigationItem.searchController = searchController
definesPresentationContext = true
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if isFiltering() {
return filteredNames.count
} else {
return names.count
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell() // don't do this, i am for example.
var name: String
if isFiltering() {
name = filteredNames[indexPath.row]
} else {
name = names[indexPath.row]
}
cell.textLabel?.text = name
return cell
}
func searchBarIsEmpty() -> Bool {
// Returns true if the text is empty or nil
return searchController.searchBar.text?.isEmpty ?? true
}
func isFiltering() -> Bool {
return searchController.isActive && !searchBarIsEmpty()
}
func filterContentForSearchText(_ searchText: String, scope: String = "All") {
filteredNames = names.filter({( name : String) -> Bool in
return name.lowercased().contains(searchText.lowercased())
})
tableView.reloadData()
}
}
extension ViewController: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
filterContentForSearchText(searchController.searchBar.text!)
}
}
let vc = ViewController()
let nav = UINavigationController()
nav.viewControllers = [vc]
PlaygroundPage.current.liveView = nav
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…