Deleting a row from a tableView with multiple rows in section

229 Views Asked by At

When I try and delete a row from a section with multiple rows, when I slide to the left to reveal the delete button and press it, it deletes it once the tableView is refreshed, but visually it does nothing. If I press it again, it deletes both rows in that section. If I dont press it again and press back and then come back to that viewController, the delete has worked but the animation never happened. Deleting a cell in a section where there is only one cell works perfectly. When there are 2 cells or more in the section, the delegate functions never get called but the commitEditingStyle does. Let me know if you need any more code. Thanks.

Here is my NSFetchedResultsControllerDelegate methods

override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {


        let object = self.fetchedResultsController.objectAtIndexPath(indexPath) as NSManagedObject
        self.context.deleteObject(object)
        try! context.save()
}

func controllerWillChangeContent(controller: NSFetchedResultsController) {

}

func controllerDidChangeContent(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?)
{
    var tableView = self.tableView as UITableView
    switch(type)
    {
    case .Delete:
        if let indexPath = indexPath
        {
            print("delete")
            tableView.deleteRowsAtIndexPaths(NSArray(object:indexPath) as! [NSIndexPath], withRowAnimation: UITableViewRowAnimation.Fade)
        }
        break
    case .Update:
        if let indexPath = indexPath
        {
            if let cell = tableView.cellForRowAtIndexPath(indexPath)
            {
            cell.textLabel!.text = (self.fetchedResultsController.valueForKey("firstName") as! String) + " " + (self.fetchedResultsController.valueForKey("lastName") as! String)
                print("update")
            }
        }
    default:
        break
    }


}

func controller(controller: NSFetchedResultsController,
    didChangeSection sectionInfo: NSFetchedResultsSectionInfo,
    atIndex sectionIndex: Int,
    forChangeType type: NSFetchedResultsChangeType)
{
    switch(type)
    {
    case .Delete:
        tableView.deleteSections(NSIndexSet(index:sectionIndex), withRowAnimation: UITableViewRowAnimation.Fade)
    break
    default:
    break
    }
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {

}

SOLUTION: I needed to add a self.tableView.reloadData() at the end of the commitEditingStyle function

override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {


        let object = self.fetchedResultsController.objectAtIndexPath(indexPath) as NSManagedObject
        self.context.deleteObject(object)
        try! context.save()
self.tableView.reloadData()
}
1

There are 1 best solutions below

2
On BEST ANSWER

Add a self.tableView.reloadData() after you delete the row, or the row is technically deleted, but the table view has not been updated yet. See updated code below...

        func controller(controller: NSFetchedResultsController,
            didChangeSection sectionInfo: NSFetchedResultsSectionInfo,
            atIndex sectionIndex: Int,
            forChangeType type: NSFetchedResultsChangeType)
        {
            switch(type)
            {
            case .Delete:

//this creates the delete annimation
                tableView.deleteSections(NSIndexSet(index:sectionIndex), withRowAnimation: UITableViewRowAnimation.Fade)

 //this deletes the row from the array
    self.array.removeAtIndex(indexPath.row)        

//this reloads the table view so you can see the row deleted.
        self.tableView.reloadData()



            break
            default:
            break
            }
        }