views:

531

answers:

2

I'm implementing a UITableView where the number of rows for a given section is limited to 4. For that matter, if the number of rows is less than 4, I add a row that is used as a placeholder for the next item to add (this is similar to the "Contacts" app).

I have a problem when I reach the maximum number of rows for the section. If I try to delete an object from that section, I get the following exception:

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

Of course, the problem is that my numberOfRowsInSection methods returns N+1 if the number of rows is less than 4 (one extra cell for the placeholder), which triggers this inconsistency exception.

Is there anyway around this?

+2  A: 

I think that this is expected. When you tell it to delete a row, it takes that literally -- it wants that row gone. It sounds like you just want to CLEAR the row, in which case I'd call reloadRowsAtIndexPaths: instead, making sure that your dataSource knows that this row should now be empty.

Or - and this might be better - you could call an insertRowsAtIndexPath: right after the delete. This would probably let you animate stuff a little better. Just make sure that you enclose the delete and insert statements with [tableView beginUpdates] and [tableView endUpdates] statements.

Edit: just reread the question. Nevermind my first answer, but I think my second answer should still work.

Ian Henry
+2  A: 

I've run into a similar problem because I provide a placeholder row to act as a guide in getting a user started with a table interaction in one application. The reason it is happening is that the number of rows in the section has to match - as the exception is saying.

The way to handle it is simple only call deleteRowsAtIndexPaths in cases where you are changing the number of rows in the section.

So in your case you are saying I have four rows all with content (presumably stored in an array or some other data structure). I am deleting one of these rows but I am going to be placing a placeholder row there in it's place. So the number of rows in the section for display purposes is actually not changing.

What you want to do then is delete the item from your data structure so that when cellForRowAtIndex gets called it will load your placeholder cell properly but you don't actually need to try and remove the row from the tableview.

Alternatively if you want to get the highlighting interaction I'd try out what Ian is suggesting by removing and adding the rows in one transaction - I haven't tested that out in this situation though.

I have found the user experience to be pretty smooth without the additional animations, but that depends on your app.

paulthenerd