2016-05-12 8 views
0

Ich habe eine Tabellenansicht innerhalb einer VC. Es wird von einem Kerndatenobjekt bevölkert mit dem folgenden Code:Wie Swipe löschen Core-Datentabellenansicht in Swift 2.0

// Variables 
var allFruits: NSArray 
var managedObjectContext: NSManagedObjectContext 
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate 

func loadFruits(){ 
    // Try to load all of the Fruits from the core data. 
    let fetchRequest = NSFetchRequest() 

    let entityDescription = NSEntityDescription.entityForName("Fruit", inManagedObjectContext: self.managedObjectContext) 

    fetchRequest.entity = entityDescription 
    do{ 
     self.allFruits = try self.managedObjectContext.executeFetchRequest(fetchRequest) 

     if self.allFruits.count == 0{ 
      print("No saved Fruits") 
     } 
    } 
    catch 
    { 
     let fetchError = error as NSError 
     print(fetchError) 
    } 
} 

Dann wird die Tabellenansicht wird mit diesen spezifischen Frucht Daten gefüllt. Ich habe diese Methode zum Löschen der Früchte aus der Tabelle jedes Mal wenn ich versuche

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { 
    if (editingStyle == UITableViewCellEditingStyle.Delete) { 
     // handle delete (by removing the data from your array and updating the tableview) 
     managedObjectContext.deleteObject(allFruits[indexPath.row] as! NSManagedObject) 

     // Attempt to save the object 
     do{ 
      try appDelegate.managedObjectContext.save() 
     } 
      catch let error{ 
      print("Could not save Deletion \(error)") 
     } 

     // Remove the deleted item from the table view 
     self.tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) 

     // Reload the fruits 
     self.loadFruits() 

     // Reload the table view 
     tableView.reloadData() 
    } 
} 

Dieser statt nur abstürzt die App bekam die Früchte zu löschen.

‚NSInternalInconsistencyException‘, Grund: ‚Ungültige Update: ungültige Anzahl der Zeilen in Abschnitt 0. Die Anzahl der Zeilen in einem bestehenden Abschnitt nach dem Update enthalten ist (5) muss auf die Anzahl der Reihen gleich in diesem Abschnitt vor dem Update (5), plus oder minus die Anzahl der Zeilen aus diesem Abschnitt eingefügt oder gelöscht (0 eingefügt, 1 gelöscht) und plus oder minus der Anzahl der Zeilen in oder aus dieser Abschnitt bewegt (0 eingezogen, 0 ausgezogen). "

mir den Verdacht, dass es einige Probleme mit der Tatsache ist, dass ich ein NSArray zu einem NSMutableArray im Gegensatz verwenden.

Wie kann ich dieses Problem beheben?

Vielen Dank im Voraus.

Antwort

0

Ich reparierte meinen Code, indem Sie einfach diese Methode zu ändern:

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { 
     if (editingStyle == UITableViewCellEditingStyle.Delete) { 


      // handle delete (by removing the data from your array and updating the tableview) 
      managedObjectContext.deleteObject(allFruits[indexPath.row] as! NSManagedObject) 

      //Attempt to save the object 
      do{ 
      try appDelegate.managedObjectContext.save() 
      } 
      catch let error{ 
      print("Could not save Deletion \(error)") 
      } 

      //Reload the fruits 
      self.loadFruits() 

      //Reload the table view 
      tableView.reloadData() 


     } 
    } 

Dieses erfolgreich als auch das Objekt von den Kerndaten löschen, wie die Tabellenansicht zu aktualisieren.

+0

Ja, dies funktioniert, weil Sie zuerst die Datenquelle aktualisieren. – Lumialxk

1

Sie sollten die Datenquelle vor dem Löschen aktualisieren. Wie folgt aus:

 //Reload the fruits 
    self.loadFruits() 

    //Remove the deleted item from the table view 
    self.tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) 

Und wenn Sie sicher sind, gibt es keine weiteren Änderungen, dann ist es keine Notwendigkeit, Daten neu laden, da dies viel kostet.

+0

Also, was mache ich falsch? Ich lösche es genauso, wie Sie es vorgeschlagen haben. –

+0

@ Tirat2131 Es tut mir so leid für meinen Fehler. Aktualisiere meine Antwort und hoffe, dass es dir hilft. – Lumialxk

2

Zunächst einmal verwenden, um einen Swift-Array statt einer Stiftung Array

var allFruits = [NSManagedObject]() 

Dies vermeidet eine Menge Art Casting.

Um Core-Daten und die Tabellenansicht synchron zu halten, müssen Sie das Objekt in den Core-Daten und im Modell löschen. Die Lösung, um sowohl das Modell als auch die Ansicht vollständig neu zu laden, ist sehr teuer und wird überhaupt nicht benötigt.

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { 
    if editingStyle == .Delete { 

    let objectToDelete = allFruits[indexPath.row] 
    allFruits.removeAtIndex(indexPath.row) 
    managedObjectContext.deleteObject(objectToDelete) 

    //Attempt to save the object 
    do{ 
     try appDelegate.managedObjectContext.save() 
     tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) 
    } 
    catch let error{ 
     print("Could not save Deletion \(error)") 
    } 
    } 
} 

deleteRowsAtIndexPaths umfasst die Benutzeroberfläche so Neuladen die Tabellen-Ansicht Aktualisierung ist nicht erforderlich.

Wenn das Modell der Tabellenansicht NSManagedObject ist es empfohlen, NSFetchedResultsController

+0

Aber dann habe ich ein Problem mit dem Code sagen: Kann keinen Wert des Typs [AnyObject] zu einem Wert des Typs [NSManagedObject] in der 'self.allFruits = versuchen self.managedObjectContext.executeFetchRequest (fetchRequest)' Teil –

+0

Sie benötigen schreibe 'self.managedObjectContext.executeFetchRequest (fetchRequest) als! [NSManagedObject] ' – vadian

0

Aktualisiert für Swift 3 Xcode 8 iOS 10

Der folgende Code-Schnipsel fügt eine ‚Swipe zu löschen‘ zu verwenden, um Ihre Tabelle Zeile, und speichert auch die Änderungen an CoreData.

override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { 
    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext 

    if editingStyle == .delete { 
     context.delete(tasks[indexPath.row] as NSManagedObject) 
     //objects.remove(at: indexPath.row) 
     tableView.deleteRows(at: [indexPath], with: .fade) 

     //Save the object 
     do{ 
      try (UIApplication.shared.delegate as! AppDelegate).saveContext() 
     } 
     catch let error{ 
      print("Cannot Save: Reason: \(error)") 
     } 

     //Reload your Table Data 
     getData() 

     //Reload the table view 
     tableView.reloadData() 

    } else if editingStyle == .insert { 
     // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view. 
    } 
}