2017-10-08 1 views
0

Ich habe eine ViewController mit einem TableView. Wenn die Anwendung läuft es durch den Fehler abstürzt:Anwendungsabsturz für Zeilenproblem (TableView, Swift)

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'

RHI Teil des Codes des Viewcontroller ist:

import UIKit 
import MapKit 
import CoreLocation 
import GoogleMaps 
import GooglePlaces 
import Social 
import AVFoundation 

private let resueIdentifier = "MyTableViewCell" 

extension UIViewController { 
    func present(viewController : UIViewController, completion : (() ->())? = nil){ 
     if let presented = self.presentedViewController { 
      presented.removeFromParentViewController() 
     } 
     self.present(viewController, animated: true, completion: completion) 
    } 
} 

class CourseClass2: UIViewController, UITableViewDelegate, UITableViewDataSource { 
    @IBOutlet weak var tableView: UITableView! 

    let minimumSpacing : CGFloat = 15 //CGFloat(MAXFLOAT) 
    let cellWidth: CGFloat = 250 
    var category : QCategoryy? 
    var places: [QPlace] = [] 
    var isLoading = false 
    var response : QNearbyPlacesResponse? 
    var rows = 0 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     self.title = category?.name 
    } 

    override func viewWillAppear(_ animated: Bool) { 
     super.viewWillAppear(animated) 

     determineMyCurrentLocation() 
    } 

    override func viewWillDisappear(_ animated: Bool) { 
     super.viewWillAppear(animated) 
    } 

    override func viewDidAppear(_ animated: Bool) { 
     super.viewDidAppear(animated) 
     rows = 0 
     tableView.reloadData() 
     insertRowsMode3() 
     category?.markView() 
    } 

    @IBAction func refreshTapped(_ sender: Any) { 
     rows = 0 
     tableView.reloadData() 
     insertRowsMode3() 
    } 

    func insertRowsMode2() { 
     for i in 0..<places.count { 
      insertRowMode2(ind: i, usr: places[i]) 
     } 
    } 

    func insertRowMode2(ind:Int,usr:QPlace) { 
     let indPath = IndexPath(row: ind, section: 0) 

     rows = ind + 1 
     tableView.insertRows(at: [indPath], with: .right) 
    } 

    func insertRowsMode3() { 
     rows = 0 
     insertRowMode3(ind: 0) 
    } 

    func insertRowMode3(ind:Int) { 
     let indPath = IndexPath(row: ind, section: 0) 
     rows = ind + 1 
     tableView.insertRows(at: [indPath], with: .right) 

     guard ind < places.count-1 else { return } 
     DispatchQueue.main.asyncAfter(deadline: .now()+0.20) { 
      self.insertRowMode3(ind: ind+1) 
     } 
    } 

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

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return places.count /* rows */ 
    } 

    public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MyTableViewCell 

     let place = places[indexPath.row] 
     cell.update(place: place) 

     if indexPath.row == places.count - 1 { 
      loadPlaces(false) 
     } 

     return (cell) 
    } 

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 
     tableView.deselectRow(at: indexPath, animated: true) 

     UIView.animate(withDuration: 0.2, animations: { 
      let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MyTableViewCell 
     }) 

     performSegue(withIdentifier: "goToLast" , sender: users[indexPath.row]) 
    } 

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 
     return 100 
    } 

    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { 
     return true 
    } 

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { 
     if editingStyle == UITableViewCellEditingStyle.delete { 
      places.remove(at: indexPath.row) 
      tableView.deleteRows(at: [indexPath], with: .fade) 
     } 
    } 
} 

einen Haltepunkt hinzufügen Ich sah, dass der Absturz in dieser func ist:

func insertRowMode3(ind:Int) { 
    let indPath = IndexPath(row: ind, section: 0) 
    rows = ind + 1 
    tableView.insertRows(at: [indPath], with: .right) 

    guard ind < places.count-1 else { return } 
    DispatchQueue.main.asyncAfter(deadline: .now()+0.20) { 
     self.insertRowMode3(ind: ind+1) 
    } 
} 

genau auf dieser Linie:

tableView.insertRows(at: [indPath], with: .right) 

Ich weiß, dass zuerst meine UITableViewDataSource aktualisieren und dann Zeilen einfügen müssen, aber ich weiß nicht, wie und was ich ändern muss, um das Problem zu lösen.

Antwort

0

Sie müssen beginnen & Ende Update-Methoden vor und nach Ihren Änderungen verwenden.

tableView.beginUpdates() 
// your modifications to the tableView 
tableView.endUpdates() 

Es teilt der TableView mit, die datasource mit der tatsächlichen tableView in diesem Zeitraum zu vergleichen.

+0

also muss ich das in meinem func insertRows [2 | 3] hinzufügen? – seran

+0

Um ausführlich zu beschreiben. Nach 'beginUpdate' beginnst du deine dataSource zu modifizieren, tableView über rowChanges zu informieren (insert, delete ...) und dann 'endUpdate' zu ​​committen alle deine Modifikationen alle zusammen, damit nichts nicht stimmt. Also ja, setze es in diese Funktionen – farzadshbfn

0

Für jeden Indexpfad, der an insertRows übergeben wird, müssen Sie ein entsprechendes Objekt zu Ihrem Array places hinzufügen. Das Datenmodell muss auf dem neuesten Stand sein, bevor Sie der Tabellenansicht Änderungen an Zeilen mitteilen.

Beachten Sie, dass Sie in Ihrer commit editingStyle Methode places korrekt aktualisieren, bevor Sie in der Tabellenansicht eine Zeile entfernen.

Ihre insertRowsMode[2|3] Methoden müssen das gleiche tun, außer natürlich müssen Sie einen Wert places hinzufügen.