When deleting a row from Uitableview using commitEditingStyle, my app crashes with this error.
Assertion failure in -[UITableView _endCellAnimationsWithContext:],
/SourceCache/UIKit_Sim/UIKit-1912.3/UITableView.m:1046 .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 (1), 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).
This is my code:
- (void)tableView:(UITableView *)tv commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
// If row is deleted, remove it from the list.
if (editingStyle == UITableViewCellEditingStyleDelete) {
order *OrderObj= [appDelegate.orderArray objectAtIndex:[indexPath row]];
[appDelegate removeitem:OrderObj];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
} }
Try to change these lines:
order *OrderObj= [appDelegate.orderArray objectAtIndex:[indexPath row]];
[appDelegate removeitem:OrderObj];
to:
[appDelegate.orderArray removeObjectAtIndex:[indexPath row]]; // assuming orderArray is NSMutableArray
Your tableView:numberOfRowsInSection: is returning bad value after the update. Check the value returned before delete and after delete. It must be decreased by 1.
Related
I only have this problems with iOS 5, no problems with iOS 6
This is my log
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 3. 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 (1), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
And my code
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [[dictionary allKeys] count];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSArray *keyArray = [dictionary allKeys];
return [[dictionary objectForKey:[keyArray objectAtIndex:section]] count];
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
= if (editingStyle == UITableViewCellEditingStyleDelete)
{
//First get all the keys of dictionary into one array
NSArray *sectionsArray = [dictionary allKeys];
//Get all the data of tapped section into one array by using indexpath.section
NSMutableArray *objectsAtSection = [dictionary objectForKey:[sectionsArray objectAtIndex:indexPath.section]];
//remove the particular object by using indexPath.row from the array
[objectsAtSection removeObjectAtIndex:indexPath.row];
// Update dictionary
[table beginUpdates];
// Either delete some rows within a section (leaving at least one) or the entire section.
if ([objectsAtSection count] > 0)
{
[dictionary setObject:objectsAtSection forKey:[sectionsArray objectAtIndex:indexPath.section]];
// Section is not yet empty, so delete only the current row.
// Delete row using the cool literal version of [NSArray arrayWithObject:indexPath]
[table deleteRowsAtIndexPaths:#[indexPath]
withRowAnimation:UITableViewRowAnimationFade];
}else{
[dictionary removeObjectForKey:[sectionsArray objectAtIndex:indexPath.section]];
// Section is now completely empty, so delete the entire section.
[table deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section]
withRowAnimation:UITableViewRowAnimationFade];
}
[table endUpdates];
}
}
in iOS 5, after delete some row, and some section, i have this problems.
Could you please help me?
Need to add
[self.tableView reloadData];
and
self.editing = YES;
This is needed because the table view doesn't initially have information about its data source and delegate; if you create a table view, it always needs to be sent a reloadData message as part of its initialization.
Hope it will Help you
Ok, it seems I found an answer. See this SO question and answer, explaining why using allKeys method is bad.
As long as you don't add or remove any elements from the dictionary, they will remain in the same order, but as soon as you add or remove an element, the new order will be completely different.
in my table view class using following methods and I am trying to delete a row of the table view
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [arrUserData count];
}
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
[self.tableView setEditing:editing animated:YES];
}
- (void)tableView:(UITableView *)tv commitEditingStyle (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if(editingStyle == UITableViewCellEditingStyleDelete)
{
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[arrUserData removeObjectAtIndex:indexPath.row];
}
}
and i have some 40 rows in the table, when i click on the red delete button on any of the rows its crashing at this line
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
with the following crash log
2012-05-30 14:58:45.835 testDeleteRow[3276:207] *** 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 (41) must be equal to the number of rows contained in that section before the update (41), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted).'
can anyone tell me how can i fix this,,thanx in advance
Actually you need to update your data source when you are deleting cells. If you are using an array for populating table then after this line -
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
you need to remove object at the same index from array. Also numbers of rows in section should be decrease by 1. if you are returning array count there then it will be automatically handle.
When you delete row from tableview, your datasource does not get updated.Say if your table contain 10 rows before deletion, then after deletion it will contain only 9 rows, whereas your data source still contain 10 values.So you have to remove the deleted value from data source explicitly.
I'm trying to get the hang of UITableViews and everything that goes with it. At the moment I have the following code:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 10;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
[cell.textLabel setText:[NSString stringWithFormat:#"I am cell %d", indexPath.row]];
return cell;
}
- (IBAction)killItem {
NSIndexPath *indexToDelete = [NSIndexPath indexPathForRow:2 inSection:0];
[tbl deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexToDelete] withRowAnimation:UITableViewRowAnimationRight];
}
And I get the following error when initiating the "killItem" function:
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 (10) must be equal to the number of rows contained in that section before the update (10), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted).'
The way I understand it tableViews basically have a delegate and a data source where the data source, among other things, determines how many rows should be in the tableView. Through some searches here at stackoverflow I've found that this error is caused when the "data source doesn't match reality", when it's searching for rows that don't exist, that I have deleted.
I might have gotten this wrong but that's what I think is doing it. So my question is, how do I get these to match so that I can avoid this error?
For reference, I've looked in to the following posts without understanding what I need to do:
Error : Number of Rows In Section in UITableView in iPhone SDK
Slide UITableViewCell
Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSMutableArray objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
Adding [tbl reloadData], [tbl beginUpdate] ... [tbl endUpdate] in the killItem function, doesen't seem to help my problem eighter.
Thank you in advance,
Tobias Tovedal
Tobias, what you need to do when deleting rows is
// tell the table view you're going to make an update
[tableView beginUpdates];
// update the data object that is supplying data for this table
// ( the object used by tableView:numberOfRowsInSection: )
[dataArray removeObjectAtIndex:indexPath.row];
// tell the table view to delete the row
[tableView deleteRowsAtIndexPaths:indexPath
withRowAnimation:UITableViewRowAnimationRight];
// tell the table view that you're done
[tableView endUpdates];
When you call endUpdate the number returned from tableView:numberOfRowsInSection: must be the same as the number at beginUpdate minus the number of rows deleted.
It's pretty easy, the problem lies here:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 10;
}
The delegate pattern used by apple, means that you're the one responsible on managing the content of the UITableView through its delegates, meaning that, if you delete a row, you're also responsible of deleting the data from the data model.
So, after deleting a row, it would make sense that the number of rows in section would decrease to "9", yet, your function is always returning 10, and thus throwing the exception.
Typically, when using an table, and the contents will change, an NSMutableArray is pretty common, you do something like this:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [arrayWithStuff count];
}
And then, deleting an object (removeObjectAtIndex:) from the array would automatically update the number of rows.
(Edit: Replied at about the same time as Mike Hay, try following his advice too! I skipped the begin/end Update, because it seems you already read about it)
In my iPhone app, I have a UITableView with the following method
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [tableArrays count];
}
Note that tableArrays is a class variable (an NSMutableArray of NSMutableArrays - representing one NSMutableArray for each section in my tableView). Now, that UITableView supports editing, and I have the following method
- (void)tableView:(UITableView *)theTableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
...some code...
NSLog(#"tableArrays count is %i",[tableArrays count]);
[tableArrays removeObjectAtIndex:indexPath.section];
NSLog(#"tableArrays is now %#",tableArrays);
NSLog(#"tableArrays count is now %i",[tableArrays count]);
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
So, I run the app and I have two sections in my table view. Row deletion works fine except when I delete the last row in a section. When I delete the last row of section 1, I see the following output, as per the code above:
tableArrays count is 2
tableArrays is now (("Blah1","Blah2"))
tableArrays count is now 1
So clearly, my tableArrays count decreases by one, but I get the following error:
...The number of sections contained in the tableView after the update (1) must be qual to the number of sections contained in the table view before the update (2), plus or minus the number of sections inserted or dleted (0 inserted, 0 deleted).'
I guess in -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; you are returning the total count of objects and you want to display only one section.
Try returning one in this method.
You should also return [tableArrays count]in -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;.
It should work better like this. Also what is section in
[tableArrays removeObjectAtIndex:section]; ? Did you mean indexPath.section ?
Thank for the comment, so the method that is returning the number of section is correct, but you to do like that to delete a cell.
NSLog(#"tableArrays count is %i",[tableArrays count]);
NSMutableArray *sectionArray = [tableArrays objectAtIndex:indexPath.section];
[sectionArray removeObjectAtIndex:indexPath.row];
//[tableArrays removeObjectAtIndex:indexPath.section];
NSLog(#"tableArrays is now %#",tableArrays);
NSLog(#"tableArrays count is now %i",[tableArrays count]);
The key is to use
[tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationFade];
when you are trying to delete the last row in a section.
I'm using Matt Gallagher's GenericTableViewController idea for controlling my UITableViews. My datasource is a NSFetchedResultsController.
http://cocoawithlove.com/2008/12/heterogeneous-cells-in.html
Everything is working fine, until I try to delete a cell.
I have the following code in my View Controller:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the managed object.
NSManagedObjectContext *context = [wineryController managedObjectContext];
[context deleteObject:[wineryController objectAtIndexPath:indexPath]];
NSError *error;
if (![context save:&error]) {
// Handle the error.
}
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
The final line crashes with the rather verbose explanation in the console:
*** 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 (5) must be equal to the number
of rows contained in that section before the update (5), plus or minus the number
of rows inserted or deleted from that section (0 inserted, 1 deleted).'
OK, I understand what it is saying... a row is not getting deleted (I would assume) because I'm not forwarding some message to the right place (since I have moved some code from its 'normal' location)... anyone have any idea which one? I am totally stumped on this one.
Well, bah. I just found this answer, which is not the same, but got me headed in the right direction. I'll leave this here for anyone in the future having similar troubles.
The key is to wrap the deleteRowsAtIndexPaths with begin and end tags, and force the model to update within the same block, resulting in:
[tableView beginUpdates];
[self constructTableGroups];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
This caused the issue to go away, and the animations to work just perfectly.