2017-01-29 8 views
1

Ich habe den folgenden Code, der von einer Benutzereingabe nehmen UISearchBar ausgelegt ist, erstellen und startet ein MKLocalSearch darauf basierend, und dann in einem UITableView alle die MKMapItem ‚s Namen anzuzeigen . Der folgende Code funktioniert nicht und stürzt, anstatt mit dem Fehler:Zellen nicht in UITableView erscheinen - Swift 3

*** 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

+2

In diesem speziellen Fall besteht keine Notwendigkeit, überhaupt die 'insert' Methode zu verwenden. Ersetzen Sie den gesamten Ausdruck 'if! Response.mapItems.isEmpty {...}' durch 'self.tableView.ReloadData() ' – vadian

+0

Danke für die Antwort, ich habe das jetzt geändert. Der Code wird erfolgreich ausgeführt, aber die Zellen erscheinen immer noch nicht in meinem 'UITableView' – spazhead

+0

Gibt es irgendwelche Elemente im 'locations' -Array, nachdem Sie versuchen, den Reload anzuhängen? – ronatory

Antwort

2

Wie über das Hinzufügen dieser Zeile in viewDidLoad Einfügen?

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

+0

Nur ein bisschen zu spät, aber habe die beste Antwort. – spazhead

0

stellte sich heraus, hatte ich nicht Setup eine richtige Datasource-Klasse zum UITableView zu verknüpfen.
die Zelle Prototyp Registrierung .xib mir erlaubt, auch keine Fehler zu erhalten, wenn die Zelle mit Wiederverwendung Kennung

+0

Ich hatte den Eindruck, dass die Zelle direkt in der Tabellenansicht gestaltet ist - was der übliche und empfohlene Weg ist. Eine zusätzliche Xib für normale Prototypzellen ist unnötig umständlich. – vadian

+0

Sorry, es sollte innerhalb des Codes entworfen werden, aber als Swift/XCode Anfänger habe ich keine Ahnung was ich mache :) – spazhead

Verwandte Themen