joshlorschy joshlorschy - 2 months ago 10
Swift Question

xCode TableView search results do not display correctly as cellForRowAt still calls upon the original, unfiltered array

I have just finished adding a search bar to my TableView. It everything works perfectly, except the data displayed in the search results still shows the objects from the original, unfiltered array (although, when I click on the results they take me to the correct DetailView of the object for which I searched).

So the search logic is working, I just am not receiving a correct visual display of the search results.

I believe the issue arises in my cellForRowAt function, in which I attempt to determine whether the cell is filled with data from the original array or the search results. This line is marked with a caution error (the yellow one!) that reads 'Initialization of immutable value 'location' was never used; consider replacing with assignment to '_' or removing it'. However, I am unsure of how else to write this line.

Please see the relevant search code below (with the error line marked using a comment - it is almost at the very bottom of this code).

var locations = [Location]()
var searchController:UISearchController!
var searchResults = [Location]()

override func viewDidLoad() {
super.viewDidLoad()

searchController = UISearchController(searchResultsController: nil)
tableView.tableHeaderView = searchController.searchBar
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false

self.tableView.reloadData()
}

func filterContent(for searchText: String) {

searchResults = locations.filter({ (location) -> Bool in
if let name = location.name {
let isMatch = name.localizedCaseInsensitiveContains(searchText)
return isMatch
}

return false

})

}


func updateSearchResults(for searchController: UISearchController) {
if let searchText = searchController.searchBar.text {
filterContent(for: searchText)
tableView.reloadData()
}
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searchController != nil && searchController.isActive {

return searchResults.count

} else {

return locations.count

}
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let cellIdentifier = "cell"
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! LocationTableViewCell

// The following line is where I receive the error, as I attempt to determine whether the app should get the result from the filtered search result
let location = (searchController.isActive) ? searchResults[indexPath.row] : locations[indexPath.row]

cell.nameLabel.text = locations[indexPath.row].name
cell.thumbnailImageView.image = UIImage(named: locations[indexPath.row].image)
cell.locationLabel.text = locations[indexPath.row].location
cell.typeLabel.text = locations[indexPath.row].type
cell.accessoryType = locations[indexPath.row].isVisited ? .checkmark : .none
return cell
}

Answer Source

You're never using location. Change your code below that line to use it:

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cellIdentifier = "cell"
        let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! LocationTableViewCell

        let location = (searchController.isActive) ? searchResults[indexPath.row] : locations[indexPath.row]

        //use the location variable you just set to set the cell's properties

        cell.nameLabel.text = location.name
        cell.thumbnailImageView.image = UIImage(named: location.image)
        cell.locationLabel.text = location.location
        cell.typeLabel.text = location.type
        cell.accessoryType = location.isVisited ? .checkmark : .none
        return cell
    }