I am working on a table UITableViewController in Xcode. Each time when I try to delete a row from the app I have 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)
Code for table load and delete row is:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.toDoItems count];}
And that's the delete method:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {}
}
I hope you could help me to fix this error!
Thank You!
You forgot to remove object from your model self.toDoItems.
Try to update your last method with such body:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.toDoItems removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {}
}
}
Related
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
PFObject *object = [_tdlArray objectAtIndex:(_tdlArray.count - indexPath.row -1)];
[object deleteInBackground];
//found the code for removing a row.
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
[tableView reloadData];
[object deleteInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (!succeeded){
[tableView reloadData];
}
}];
}
}
I am able to successfully remove the data, but my app would crash every time I tap on the delete button. I think it has something to do with the [NSArray arrayWithObject:indexPath]
These are the error message
Assertion failure in -[UITableView _endCellAnimationsWithContext:]
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).'
You want to delete the object then reload the data. Don't dispatch asynchronously the object to be deleted then tell the tableview you're deleting rows because the object has likely not been deleted yet, hence the error you're getting. Use the callback block to update the tableview after the object has been removed that way you can be sure that the object has been deleted. Also if you have a local store of the data that not bound to the data on the server, you need to remove the object from there as well.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
//not sure how you're calculating the index here
PFObject *object = [_tdlArray objectAtIndex:(_tdlArray.count - indexPath.row -1)];
NSMutableArray *mutArray = [_tdlArray mutableCopy];
[mutArray removeObject:object];
_tdlArray = [NSArray arrayWithArray:mutArray];
[object deleteInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (!succeeded){
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
[tableView reloadData];
}
}];
}
}
I have a tableview that displays your friends, and I'm making this table editable. You can add friends by tapping the last row, which says "ADD FRIEND". When you want to delete a friend, you tap edit on the navigation bar, and you can delete whichever row you want. Problem is: you can also delete the last row that says "ADD FRIEND". How can I make the last row undeletable? I dont want to show the "deletable" animation on the last cell (the red circle).
Code is pretty basic, see below.
.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
FriendsListTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"friendID" forIndexPath:indexPath];
// Configure the cell...
NSInteger totalRow = [tableView numberOfRowsInSection:indexPath.section]; //first get total rows in that section by current indexPath.
if(indexPath.row == totalRow -1){
//this is the last row in section.
AddFriendIndexRow = totalRow-1;
cell.friendName.text = #"+ ADD FRIEND";
} else {
cell.friendName.text = friendsList[indexPath.row];
}
return cell;
}
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[friendsList removeObjectAtIndex:indexPath.row];
NSLog(#"friendslist: %#", friendsList);
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
} else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
You're going to want to use the canEditRowAtIndexPath data source method and do something like this:
- (BOOL)tableView:(UITableView * _Nonnull)tableView canEditRowAtIndexPath:(NSIndexPath * _Nonnull)indexPath {
if (indexPath == //Last index path)
return NO
else return YES
}
You are returning NO for the last indexPath in your tableView and YES for all others. This will make all rows editable except for your last one. More documentation can be found here on Apple's Site:
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableViewDataSource_Protocol/#//apple_ref/occ/intfm/UITableViewDataSource/tableView:canEditRowAtIndexPath:
I added the following code in my iOS app to delete table cell from UITableViewController, but I get an error about the deletion.
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
if(editingStyle == UITableViewCellEditingStyleDelete){
[self.toDoItems removeObjectAtIndex:indexPath.row];
NSArray *indexPaths = #[indexPath];
[self.tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
Update:
toDoItems is just an NSArray, and I have tried the following code but is still not working:
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
if(editingStyle == UITableViewCellEditingStyleDelete){
NSArray *indexPaths = #[indexPath];
[self.tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationAutomatic];
[self.toDoItems removeObjectAtIndex:indexPath.row];
}
}
the error message is here:
'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 1. The number of rows contained in an existing section after the update (1003) must be equal to the number of rows contained in that section before the update (1004), 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).'
Xcode 6.2 iOS6
I have already tried Deleting table cell causes crash
The problem is that you are deleting the wrong object from your data model:
[self.toDoItems removeObjectAtIndex:indexPath.row];
That's too simple-minded. You have multiple sections in this table. You need a data model that distinguishes these sections, and you need to delete the correct row from the correct section in your data model before deleting the corresponding row from the table. You cannot do that by looking at indexPath.row alone; you need to structure your data model so as to take account of indexPath.section as well.
I have a editable tableView and i cant remove the last object heres my method :
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView beginUpdates];
if (editingStyle == UITableViewCellEditingStyleDelete)
{
[self deletePermittedFriend:[friendsIDs objectAtIndex:indexPath.row]];
[tableDataList removeObjectAtIndex:indexPath.row];
}
[tableView endUpdates];
}
and if the tableDataList MutableArray have only one last object gives me an error :
* Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit/UIKit-2380.17/UITableView.m:1070 2013-05-21
11:41:47.306 EzMall[3398:907] * 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 (0) 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).'
It looks that you forgot to call this UITableView method:
– deleteRowsAtIndexPaths:withRowAnimation:
BTW: It is always good practice to read error messages.
Try this
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
[tableDataList removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView endUpdates];
}
I am getting the error below from the following code:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[self.tableView reloadData];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[[FavouritesController sharedController] removeFavouriteAtIndex:indexPath.row];
[self.tableView reloadData];
}
else if (editingStyle == UITableViewCellEditingStyleNone) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
Please can you tell me how to fix it?
*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit/UIKit-1448.89/UITableView.m:995
2011-04-19 21:30:17.854 APPNAME[546:707] *** 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 (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).'
Change your model before you change your table.
So try:
[[FavouritesController sharedController] removeFavouriteAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
You probably don't need all those reloads unless the model changes more than just that one index path. The row deletion does some reloading on its own.
You probably want this code:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[[FavouritesController sharedController] removeFavouriteAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleNone) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}