Search code examples
iosswiftuisearchresultscontroller

searchResults not showing correct words


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.

enter image description here enter image description here

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?


Solution

  • 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