2

I'm trying to implement a custom deletion process for my app, as my costumer doesn'y want the red circle provided by table view edition mode. I have added a deletion button for every row, with row number in its tag property. Once user clicks deletion button, it fires following method:

-(IBAction)deleteRow:(id)sender{

    UIButton *tempButton = (UIButton*)sender;

   [self updateTotals];

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:tempButton.tag inSection:0];

    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]  withRowAnimation:UITableViewRowAnimationFade];

    [tableView reloadData];

    [sharedCompra removeItem:tempButton.tag];

    tempButton=nil;


}

And I allways get this error:

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 (3) must be equal to the number of rows contained in that section before the update (3), 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).'

So I don't know if I'm missing something in this piece of code.

Many thanks.

3 Answers 3

12

You're trying to delete a row whereas your data source still reflects the original state (i. e. that before the deletion). You have to update the data source first, it's only then that you can issue a deletion from the table viev. You also don't need to set the button to nil, nor do you need to call - reloadData on the table view:

- (void)deleteRow:(id)sender
{
    UIButton *tempButton = sender;
    [self updateTotals];

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:tempButton.tag inSection:0];
    [sharedCompra removeItem:tempButton.tag];

    [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]  withRowAnimation:UITableViewRowAnimationFade];
}

(One thing you should do, however, is paying attention to how you format your code.)

Sign up to request clarification or add additional context in comments.

Comments

1

Call [sharedCompra removeItem:tempButton.tag]; before [tableView deleteRowsAtIndexPaths... and [tableView reloadData]

The problem is that when you call deleteRowsAtIndexPath: it is calling numberOfRowsInSection which returns the same count from your model.

Also reloadData call is not needed here.

Comments

0

When deleting and adding rows, you need to call beginUpdates, here how it should look.

[tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]  withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];

and you don't need to call reloadData, or it will cancel the animation of the deleteRows, and insertRows methods. But you do need to reset the data, so if you're using an NSMutableArray, you need to remove the object first, so item at index 0, then you can delete row 0 in table. the number of rows needs to match the number of objects in that array when it ends deleting or it will also crash.

2 Comments

Um, no. You do not need to call - beginUpdates and - endUpdates. The problem is not that.
You use beginUpdates and endUpdates when you are inserting/deleting/reloading multiple rows and you need the index paths to remain consistent throughout. But as @H2CO3 stated, that is completely unrelated to this question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.