如何在Swift 2.0中滑动删除核心数据tableview

时间:2016-05-12 03:42:46

标签: ios swift uitableview core-data

我在VC中有一个表视图。它使用以下代码从核心数据对象填充:

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

然后使用此特定水果数据填充表格视图。我有这种方法从表中删除水果

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

每次我尝试删除水果时,这都会导致应用程序崩溃。

  

'NSInternalInconsistencyException',原因:'无效更新:无效   第0节中的行数。包含在中的行数   更新后的现有部分(5)必须等于数量   更新前的该部分中包含的行(5),加号或减号   从该部分插入或删除的行数(插入0,   删除1)加上或减去移入或移出的行数   该部分(0移入,0移出)。'

我怀疑我使用NSArray而不是NSMutableArray这一事实存在一些问题。

如何解决此问题?

提前致谢。

4 个答案:

答案 0 :(得分:2)

首先使用Swift数组而不是Foundation数组

var allFruits = [NSManagedObject]()

这避免了大量的类型转换。

要使Core Data和表格视图保持同步,您必须删除模型中Core Data 中的对象。完全重新加载模型和视图的解决方案非常昂贵,根本不需要。

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包括更新UI,因此不需要重新加载表视图。

如果表格视图的模型为NSManagedObject,建议您使用NSFetchedResultsController

答案 1 :(得分:1)

您应该在删除之前更新数据源。像这样:

     //Reload the fruits
     self.loadFruits()

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

如果您确定没有其他更改,则无需重新加载数据,因为这会花费很多。

答案 2 :(得分:0)

我只需更改此方法即可修复我的代码:

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


        }
    }

这成功地从核心数据中删除对象以及更新表视图。

答案 3 :(得分:0)

针对Swift 3 Xcode 8 iOS 10进行了更新

以下代码段添加“轻扫”以删除'到表行,并将更改保存到CoreData。

<hr>