Reputation: 1481
I have a search which downloads a JSON file and displays the results in a TableView. If the user searches for something and gets a list of results, then searches for something else which returns 0 results. The first set of results is still in the TableView. I want to clear the TableView each time a new search starts to prevent that happening. I've tried setting the data source to nil and reloading the TableView but it's not working. Here's what I have:
var searchResults : [[String : AnyObject]]? = nil
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
print("DEBUG: searchBarSearchButtonClicked")
if searchBar.text > "" {
//--- This isn't working ---
searchResults = nil
tableView.reloadData()
//--------------------------
activityIndicator.startAnimating()
dbSearcher.startSearch(searchBar.text!) { (results) -> () in
self.searchResults = results
self.activityIndicator.stopAnimating()
self.tableView.reloadData()
}
searchBar.endEditing(true)
}
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searchResults != nil {
print("DEBUG: Result count \(searchResults!.count)")
return searchResults!.count
} else {
print("DEBUG: Result count 0") //I don't see this other than when the ViewController first loads
return 0
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell : UITableViewCell = tableView.dequeueReusableCellWithIdentifier("searchResult")!
cell.textLabel?.text = searchResults![indexPath.row]["Title"] as? String
cell.detailTextLabel?.text = searchResults![indexPath.row]["Year"] as? String
//Display cover
let imageURL = searchResults![indexPath.row]["Poster"] as? String
if imageURL != "N/A" {
if let cover : UIImage = searchResults![indexPath.row]["Image"] as? UIImage {
cell.imageView?.image = cover
} else {
//Use default cover while the correct image downloads
//cell.imageView?.image = DEFAULT_COVER
downloadCover(imageURL!, tableViewRow: indexPath.row)
}
} else {
//Use default cover
//cell.imageView?.image = DEFAULT_COVER
}
return cell
}
Upvotes: 10
Views: 37901
Reputation: 285082
Don't use an optional type.
Declare an non-optional empty array.
var searchResults : [[String : Any]]()
then numberOfRowsInSection
can be just
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return searchResults.count
}
To clear the table view write
searchResults.removeAll()
tableView.reloadData()
No unwrapping, no checking for nil
, no problems.
Upvotes: 27
Reputation: 2463
This post was a long time ago, but for anyone interested, here is what I use in my app.
If you really want to use the deleteRows
function (for animation purposes for instance), then you can do the following:
let count = self.tableView(self.tableView, numberOfRowsInSection: 0)
// insert action that deletes all your data from the model here
// e.g. self.arrayOfRows = []
self.tableView.deleteRows(at: (0..<count).map({ (i) in IndexPath(row: i, section: 0)}), with: .automatic)
What it basically does is convert the range 0..<count
to [IndexPath]
values and instructs the table view to delete those paths, using the deleteRows
method.
Upvotes: 2