2017-01-28 10 views
0

スウィフト:カントのUITableViewに行を挿入 - 私はアプリがエラーでクラッシュし、次のコード持っている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' 

をStackOverflowの上で記載されているように私には、複数の解決策を試してみましたが、どれもこのエラーを止めることはできません。

が試み:

コード:

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 localSearchResponse != nil { 
       let toNum = localSearchResponse?.mapItems.count ?? 0 
       for i in stride(from: 0, to: toNum, by: 1) { 
        self.locations.append((localSearchResponse?.mapItems[i])!) 
        print((localSearchResponse?.mapItems[i])!) 
       } 
       self.tableView.insertRows(at: [IndexPath(row: 0, section: 0)], with: UITableViewRowAnimation(rawValue: 5)!) 
      } 
     } 
    } 

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

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

    func tableView(tableView: UITableView, cellForRowAt indexPath: NSIndexPath) -> UITableViewCell { 
     let cell = self.tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath as IndexPath) 
     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 viewDidDisappear(_ animated: Bool) { 
     searchController.searchBar.isHidden = true 
    } 
} 

EDIT:をこれはまだ同じエラーが発生し

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) 
      } 
     } 
    } 


attempt to insert row 0 into section 0, but there are only 0 rows in section 0 after the update次のようヴァディアンが提案新しいlocalSearch.startという使い方。
助けていただければ幸いです。

+0

をお勧めしたいすべての行のアニメーションを使用しないように:戻りself.locations.countを。 ?そして、numberOfSections()メソッドを削除するだけで、1セクションが必要になります。 – Mamta

答えて

1

はあなたのコードでは、2つの主要な問題だ:

  • マップ項目の数が0であっても、とにかく1行が挿入されます。 (これがエラーの原因となりました)。
  • 複数のマップ項目がある場合は、行だけが挿入されます。

この

if let response = localSearchResponse { 
     for mapItem in response.mapItems { // please not those ugly C-stlye loops 
      self.locations.insert(mapItem, at:0) 
      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) 
     } 
    } 

はノートのようなもの試してみてください:UITableViewRowAnimation(rawValue: 5)!.noneは後者がはるかに短いと劇的により記述され、まったく同じです。

しかし、あなたは私はあなたがこの行の末尾にセミコロンを持っていないのはなぜ

if let response = localSearchResponse { 
     for mapItem in response.mapItems { 
      self.locations.append(mapItem) 
      print(mapItem) 
     } 
     self.tableView.reloadData() 
    } 
+0

2番目のオプションを使用することにしましたが、私のUITableViewにセルは表示されません。私は実装する必要がある別の機能はありますか? – spazhead

+0

それは別の質問です。 'print(mapItem)'は何も印刷しませんか? – vadian

+0

はい、 'print(mapItem)'は1つ以上のMKMapItemを出力します。申し訳ありませんが私の元の質問は私の意図した結果が明らかでない場合。 – spazhead

1

ネットワーク通話からデータを取得した後で、あなたのUITableviewをリロードしようとしてください。

https://developer.apple.com/reference/uikit/uitableview/1614862-reloaddata

(あなたが挿入されている場所がフェッチされ、したがって、テーブルビューの行がまだ0である前に)

おかげ スリラム

+0

私の行が挿入されているにもかかわらずセルが私のUITableView(self.tableView)に表示されないと 'self.tableView.reloadData()'を追加しました – spazhead

関連する問題