spazhead
spazhead

Reputation: 304

Cells not appearing in UITableView - Swift 3

I have the following code, which is designed to take user input from a UISearchBar, create and start a MKLocalSearch based on it, and then display all of the MKMapItem's names in a UITableView. The following code does not work and instead crashes with the error:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to insert row 0 into section 0, but there are only 0 rows in section 0 after the update'

Code:

import UIKit
import MapKit

class TableViewController: UITableViewController, UISearchResultsUpdating {

    var localSearchRequest:MKLocalSearchRequest!
    var localSearch:MKLocalSearch!
    var localSearchResponse:MKLocalSearchResponse!
    var locations = [MKMapItem]()

    @available(iOS 8.0, *)
    public func updateSearchResults(for searchController: UISearchController) {
        localSearch?.cancel()
        localSearchRequest = MKLocalSearchRequest()
        localSearchRequest.naturalLanguageQuery = searchController.searchBar.text
        localSearch = MKLocalSearch(request: localSearchRequest)
        localSearch.start { (localSearchResponse, error) -> Void in
            if let response = localSearchResponse {
                self.locations.removeAll()
                for mapItem in response.mapItems {
                    self.locations.append(mapItem)
                    print(mapItem)
                }
                if !response.mapItems.isEmpty {
                    let indexPaths = (0..<response.mapItems.count).map { IndexPath(row: $0, section: 0) }
                    self.tableView.insertRows(at: indexPaths, with: .none)
                }
            }
        }
    }

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

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.locations.count;
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as UITableViewCell
        let row = indexPath.row
        cell.textLabel?.text = self.locations[row].name
        return cell
    }

    let searchController = UISearchController(searchResultsController: nil)

    override func viewDidLoad() {
        super.viewDidLoad()
        searchController.searchResultsUpdater = self
        searchController.hidesNavigationBarDuringPresentation = false
        searchController.dimsBackgroundDuringPresentation = false
        searchController.searchBar.sizeToFit()
        searchController.searchBar.tintColor = UIColor(colorLiteralRed: 1, green: 1, blue: 1, alpha: 1)
        searchController.searchBar.placeholder = "Location"
        searchController.searchBar.returnKeyType = UIReturnKeyType(rawValue: 6)!
        self.tableView.tableHeaderView = searchController.searchBar
    }

    override func viewWillDisappear(_ animated: Bool) {
        searchController.isActive = false
        searchController.searchBar.isHidden = true
    }

    override func viewDidDisappear(_ animated: Bool) {
        searchController.isActive = false
        searchController.searchBar.isHidden = true
    }
}

.
TableViewController Outlets:

TableViewController Outlets

Upvotes: 1

Views: 1223

Answers (2)

thy.nguyen
thy.nguyen

Reputation: 130

How about adding this line in your viewDidLoad?

tableView.register(UITableViewCell.classForCoder(), forCellReuseIdentifier: "Cell")

Upvotes: 3

spazhead
spazhead

Reputation: 304

Turns out I had not setup a proper dataSource Class to link to the UITableView.
Registering the cell prototype .xib also allowed me to not get errors when inserting the cell with reuse identifier

Upvotes: 1

Related Questions