Daniel
Daniel

Reputation: 1481

Swift - Clear TableView

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

Answers (3)

user11137399
user11137399

Reputation: 1

Try this:

tableView.getItems().clear();

Upvotes: -3

vadian
vadian

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

Alexandre Cassagne
Alexandre Cassagne

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

Related Questions