Search code examples
iosarraysswiftuitableviewuisearchcontroller

Using searchController to filter tableView, but the tableView isn't updating


I have a UITableViewController that is displaying the titles of Tags I created. When I first navigate to the UITableViewController, it displays the Array of Tags just fine, but when I use the UISearchController to filter through Tags, the Array I created to store the filtered results updates and holds the correct data, but the TableView doesn't change. here are the two functions that are most likely causing the problem, but just in case, I will have the entire class (not long) down below.
numberOfRowsInSection:

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if(searchController.searchBar.text != "") {
        return filteredTags.count
    }
    return Tags.count
}

cellForRowAt:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "tagcell", for: indexPath) as! TagCell

    var text = ""
    if (searchController.searchBar.text != ""){
        text = filteredTags[indexPath.row].title
    } else {
        text = Tags[indexPath.row].title
    }

    cell.cellLabel.text = text
    return cell
}

Whole Class:

class TagCell: UITableViewCell{

    @IBOutlet weak var cellLabel: UILabel!
}

class TagTableVC: UITableViewController{

    //Table Content

    var Tags: [Tag] = [globTS.animals, globTS.civilrights, globTS.guncontrol, globTS.gunrights, globTS.LGBTQ, globTS.prochoice, globTS.prolife]
    var filteredTags = [Tag]()

    //Searchbar Initialization
    let searchController = UISearchController(searchResultsController: nil)

    //Required Functions
    override func viewDidLoad() {
        super.viewDidLoad()
        searchController.searchResultsUpdater = self
        searchController.dimsBackgroundDuringPresentation = false
        definesPresentationContext = true
        tableView.tableHeaderView = searchController.searchBar
    }

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if(searchController.searchBar.text != "") {
            return filteredTags.count
        }
        return Tags.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "tagcell", for: indexPath) as! TagCell

        var text = ""
        if (searchController.searchBar.text != ""){
            text = filteredTags[indexPath.row].title
        } else {
            text = Tags[indexPath.row].title
        }

        cell.cellLabel.text = text
        return cell
    }

    //Filters Tags array into Filtered array based on search query
    func filterContentForSearchText(searchText: String, scope: String = "All"){
        filteredTags = Tags.filter{ $0.title.lowercased().contains(searchText.lowercased())}
    }
}

extension TagTableVC: UISearchResultsUpdating {

    //calls the filter function everytime the searchbar is activated
    func updateSearchResults(for searchController: UISearchController) {
        filterContentForSearchText(searchText: searchController.searchBar.text!)
    }
}

Solution

  • After reevaluating the filteredTags, you should call reloadData on your tableview

        func filterContentForSearchText(searchText: String, scope: String = "All"){
            filteredTags = Tags.filter{ $0.title.lowercased().contains(searchText.lowercased())}
            self.tableView.reloadData()
        }