删除带有CoreData和NSFetchedResultsController的UITableView行

时间:2016-12-03 11:55:41

标签: ios swift core-data swift3

尝试从tableView中删除一行后,应用程序终止并出现以下错误:

Terminating app due to uncaught exception
'NSInternalInconsistencyException', reason: 'Invalid update: invalid
number of rows in section 0.  The number of rows contained in an
existing section after the update (2) must be equal to the number of
rows contained in that section before the update (2), plus or minus
the number of rows inserted or deleted from that section (0 inserted,
1 deleted) and plus or minus the number of rows moved into or out of
that section (0 moved in, 0 moved out).'

这里是代码:

import UIKit
import CoreData

class PlayerTableViewController: UITableViewController {


lazy var fetchedResultsController:NSFetchedResultsController<TCSpieler> = {
    let fetch:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "TCSpieler")
    let sortByName = NSSortDescriptor(key: "name", ascending: true)
    fetch.sortDescriptors = [sortByName]
    let managedObjectContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    let frc = NSFetchedResultsController(fetchRequest: fetch, managedObjectContext: managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)
    try! frc.performFetch()
    return frc as! NSFetchedResultsController<TCSpieler>
}()

// MARK: - Table view data source

override func numberOfSections(in tableView: UITableView) -> Int {
    return fetchedResultsController.sections?.count ?? 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return fetchedResultsController.sections![section].numberOfObjects
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "PlayerCell", for: indexPath) as! PlayerTableViewCell
    // Configure the cell...
    cell.player = fetchedResultsController.object(at: indexPath)

    return cell
}


// Override to support conditional editing of the table view.
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    // Return false if you do not want the specified item to be editable.
    return true
}

// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
    let rowToDelete = fetchedResultsController.object(at: indexPath)
    fetchedResultsController.managedObjectContext.delete(rowToDelete)
        try! fetchedResultsController.managedObjectContext.save()

        // Delete the row from the data source
        tableView.deleteRows(at: [indexPath], with: .fade)
    } 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
    }

}

2 个答案:

答案 0 :(得分:0)

这对我有用:

bin_PROGRAMS = ....

if ENABLE_MYPROG
  bin_PROGRAMS += myprog
endif

答案 1 :(得分:0)

这很快就可以实现

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {

        if editingStyle == UITableViewCellEditingStyle.delete {
            let managedObjectContext: NSManagedObjectContext = (UIApplication.shared.delegate as! AppDelegate).managedObjectContext;
            let managedObject: NSManagedObject = fetchedResultsController.object(at: indexPath) as! NSManagedObject;
            managedObjectContext.delete(managedObject);
            do {
                try managedObjectContext.save();
            } catch {
                // Error occured while deleting objects
            }



        } else if editingStyle == UITableViewCellEditingStyle.insert {

        }

}

此外,以下内容将负责更新用户界面 数据库何时更新

extension PlayerTableViewController: NSFetchedResultsControllerDelegate {

    func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        self. tableView.beginUpdates()
    }

    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {

        switch type {
        case .insert:
            self. tableView.insertRows(at: [newIndexPath! as IndexPath], with: .fade)
        case .delete:
            self. tableView.deleteRows(at: [indexPath! as IndexPath], with: .fade)
        case .update:
            if(indexPath != nil) {
                let cell = self. tableView.cellForRow(at: indexPath! as IndexPath)
            }
        case .move:
            self. tableView.deleteRows(at: [indexPath! as IndexPath], with: .fade)
            self. tableView.insertRows(at: [indexPath! as IndexPath], with: .fade)
        }
    }

    func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        self. tableView.endUpdates()
    }

}