I have a searchResultsViewController in my iOS application that displays an array of data for the user to be able to search through. When I try to search a random letter, lets say P for instance it does not show any of the words containing P.
the code that I used to create this searchResults is,
var array = ["Assembly", "Auto Care", "Electronic Help", "Item Delivery", "Handyman", "House Chores", "Junk Removal", "Lawn & Yard Care", "Moving", "Painting", "Pet Care", "Seasonal Work"]
var selectedItems = [String]()
var searchController = UISearchController()
var filteredArray = [String]()
var resultsController = UITableViewController()
override func viewDidLoad() {
super.viewDidLoad()
searchController = UISearchController(searchResultsController: resultsController)
tableView.tableHeaderView = searchController.searchBar
searchController.searchResultsUpdater = self
resultsController.tableView.delegate = self
resultsController.tableView.dataSource = self
searchController.searchBar.showsCancelButton = true
searchController.searchBar.showsScopeBar = true
searchController.searchBar.delegate = self
let attributes = [NSAttributedString.Key.foregroundColor: GREEN_Theme]
UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).setTitleTextAttributes(attributes, for: UIControl.State.normal)
UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).title = "Done"
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
done()
}
func updateSearchResults(for searchController: UISearchController) {
filteredArray = array.filter({ (array:String) -> Bool in
if array.contains(searchController.searchBar.text!) {
return true
} else {
return false
}
})
resultsController.tableView.reloadData()
searchController.automaticallyShowsCancelButton = true
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if selectedItems.contains(array[indexPath.row]) {
selectedItems.remove(at: selectedItems.firstIndex(of: array[indexPath.row])!)
tableView.cellForRow(at: indexPath)?.accessoryType = .none
} else {
selectedItems.append(array[indexPath.row])
tableView.cellForRow(at: indexPath)?.accessoryType = .checkmark
}
tableView.reloadData()
print(selectedItems)
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView == resultsController.tableView {
return filteredArray.count
} else {
return array.count
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = array[indexPath.row]
if selectedItems.contains(array[indexPath.row]) {
cell.accessoryType = .checkmark
}else{
cell.accessoryType = .none
}
return cell
}
any thoughts?
Use this function to filter stuff:
extension SearchVC: UISearchBarDelegate{
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
fetchedData = []
if searchText == ""{
fetchedData = items
} else {
for words in items{
if
words.item.lowercased().contains(searchText.lowercased()){
filteredData.append(words)
}
}
}
table.reloadData()
}
}
Where fetchedData
is an empty string array and items
is your array.
If the search bar is empty fetchedData
will be filled with all of your items, else just with the matched ones.
Now, the most important thing to do is to use fetchedData
instead of items
to display the results and the count properly. So, for instance:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return filteredData.count
}
Furthermore, as other users pointed out in the comments, you should really check your cellForRowAt
. Try this link: https://stackoverflow.com/a/34345245/10408872