2017-08-08 120 views
0

Xcode返回一個錯誤,指出表視圖無法從其數據源獲取單元格。我正在使用搜索欄輸入搜索詞,並在表格視圖中顯示它。無法從數據源獲取單元格?

我的第一個想法是檢查,我已經正確設置了細胞標識符cell,這是正確的,但我認爲在這段代碼中可能有其他的東西。如果有必要,我可以添加我的代碼的其餘部分,但我只是想看看我是否首先在這裏失去了一些東西。

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCellWithIdentifier("cell")! 
     let selectedItem = searchedItems[indexPath.row].placemark 
     cell.textLabel?.text = selectedItem.name 
     cell.detailTextLabel?.text = "" 
     return cell 
    } 
} 

編輯從兩個視圖控制器添加完整的代碼。到目前爲止的目標是獲得用戶的位置,然後能夠輸入搜索項,例如,在搜索欄中定位,並在表格視圖中顯示搜索結果。

第一個視圖控制器

import UIKit 
import MapKit 
import CoreLocation 

class ViewController: UIViewController { 

    //this variable is for access to the location manager throughout the scope of the controller 
    let locationManager = CLLocationManager() 

    @IBOutlet weak var mapView: MKMapView! 

    var resultSearchController:UISearchController? = nil 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     locationManager.delegate = self 
     locationManager.desiredAccuracy = kCLLocationAccuracyBest 
     locationManager.requestWhenInUseAuthorization() //this triggers authorization alert - one time only 
     locationManager.requestLocation() //triggers an also one time location request 

     let locationSearchTable = storyboard!.instantiateViewController(withIdentifier: "LocationSearchTable") as! LocationSearchTable 
     resultSearchController = UISearchController(searchResultsController: locationSearchTable) 
     resultSearchController?.searchResultsUpdater = locationSearchTable 


     //configure the search bar and embed within the navigation bar 
     let searchBar = resultSearchController!.searchBar 
     searchBar.sizeToFit() 
     searchBar.placeholder = "Search for places" 
     navigationItem.titleView = resultSearchController?.searchBar 

     //configure the UISearchController appearance 
     resultSearchController?.hidesNavigationBarDuringPresentation = false //ensure search bar is accessible at all times 
     resultSearchController?.dimsBackgroundDuringPresentation = true //for when search bar is selected 
     definesPresentationContext = true 

     locationSearchTable.mapView = mapView //passes along a handle of the mapView from the main VC onto the locationSearchTable 

    } 

} 

//extension used for code organization to group delegate methods 

extension ViewController : CLLocationManagerDelegate { 

    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { 
     if status == .authorizedWhenInUse { //is user responded with allow 
      locationManager.requestLocation() //essentially requesting on the double as first is a permission failure before allow is pressed 
     } 
    } 

    //gets called when location information comes back. You get an array of locations but only interested in first item. Eventually will zoom to this location 
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 

     if let location = locations.first { 
      let span = MKCoordinateSpanMake(0.05, 0.05) //span is the zoom level set at arbitrary level for now 
      let region = MKCoordinateRegionMake(location.coordinate, span) 
      //once you combine coordinate and span into a region you can zoom using setRegion(_:animated:) 
      mapView.setRegion(region, animated: true) 
     } 
    } 

    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { 
     print("error:: (error)") 
    } 

} 

第二個視圖控制器

import UIKit 
import MapKit 


class LocationSearchTable : UITableViewController { 

    var matchingItems:[MKMapItem] = [] //for stashing search results for easy access 
    var mapView: MKMapView? = nil //search queries rely on map region for local results. This is ahandle to the map from the previous screen 



    //this method converts the placemark to a custom address format like: "4 Melrose Place, Washington DC" 

    func parseAddress(selectedItem:MKPlacemark) -> String { 
     // put a space between "4" and "Melrose Place" 
     let firstSpace = (selectedItem.subThoroughfare != nil && selectedItem.thoroughfare != nil) ? " " : "" 
     // put a comma between street and city/state 
     let comma = (selectedItem.subThoroughfare != nil || selectedItem.thoroughfare != nil) && (selectedItem.subAdministrativeArea != nil || selectedItem.administrativeArea != nil) ? ", " : "" 
     // put a space between "Washington" and "DC" 
     let secondSpace = (selectedItem.subAdministrativeArea != nil && selectedItem.administrativeArea != nil) ? " " : "" 
     let addressLine = String(
      format:"%@%@%@%@%@%@%@", 
      // street number 
      selectedItem.subThoroughfare ?? "", 
      firstSpace, 
      // street name 
      selectedItem.thoroughfare ?? "", 
      comma, 
      // city 
      selectedItem.locality ?? "", 
      secondSpace, 
      // state 
      selectedItem.administrativeArea ?? "" 
     ) 
     return addressLine 
    } 

} 

extension LocationSearchTable : UISearchResultsUpdating { 
    func updateSearchResults(for searchController: UISearchController) { 
     guard let mapView = mapView, let searchBarText = searchController.searchBar.text else { return } 
     let request = MKLocalSearchRequest() 
     request.naturalLanguageQuery = searchBarText 
     request.region = mapView.region 
     let search = MKLocalSearch(request: request) 
     search.start { //executes the search query 
      response, _ in guard let response = response else { 
       return 
      } 
      self.matchingItems = response.mapItems 
      self.tableView.reloadData() 
     } 
    } 


} 
+0

如何定義單元格。它在代碼中嗎?你有沒有使用tableview註冊單元標識符?你是否加入了這段代碼,看看每一行發生了什麼? – Abizern

+0

您必須忘記註冊單元格。 – Ryan

+0

通過註冊單元格標識符,你只是在tableview中設置單元格標識符名稱?如果是這樣,我通過屬性檢查器來做到這一點。還是你的意思是別的?該單元格是故事板桌面視圖中的原型。 – cheznead

回答

0

兩件事情。

  1. 確保您已分配正確的數據源。

  2. 確保你已經在你的數據源中說過它是UITableView的數據源。它符合UITableViewDataSource類似YourViewController : UITableViewDataSource

+0

該類繼承自UITableViewController,因此它表示符合數據源協議是多餘的。當我正在學習一個教程時,將會發布所有的代碼以供審查,它爲我覆蓋了很多新的領域。 – cheznead