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.
Related
Can some one suggest what is the problem in my code.....
self.modleClass.foldersAray have one object and tableview have one section and one row
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[self.tableview setEditing:YES animated:YES];
[self.modleClass.foldersAray removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YEs];
[tableView reloadData];
}
}
I am getting error as below.
*** 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 (1) 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).'
Do like this,
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.modleClass.foldersAray removeObjectAtIndex:indexPath.row];
[tableView reloadData];
}
}
it is more enough.........
If your tableView is based on the foldersAray, then removing an object from this array and reloading the tableview will result in the deletion of this cell.
You could remove the line:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YEs];
This error means, that you must update you datasource (array with data, dictionary or whatever you use)
For example:
You have 5 cells before delete and 5 object in dataArray. Before call to deleteRowsAtIndexPaths: we must remove object from dataArray, that associated with this cell and only then call deleteRowsAtIndexPaths:. Also instead use [tableView reloadData], use
[tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView endUpdates];
P.S. I see, that you remove object from your datasource, so check it carefully, maybe you miss something
If you want animation try this, if you dont want animation use #Mountain Lion's answer.
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete)
{
[self.modleClass.foldersAray removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]withRowAnimation:UITableViewRowAnimationFade];
}
}
And if you have edit button on navigation, you should call
[self.tableView setEditing:YES animated:YES];
inside of your method to start editting.
IF the memory it takes does not matter for you... then you can dramatically delete (hide) cell by setting height to 0.
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row%2) {
return 0;
}
return 100;
}
P.S: above dummy code will dramatically delete alternate cells.
I have my search display view controller based off TableSearch.
Normally, following expression gives selected index row:
self.tableView.indexPathForSelectedRow.row
However while in search mode, selected row can be obtained using:
self.searchDisplayController.searchResultsTableView.indexPathForSelectedRow.row
I use the above indices to remove respective rows (from my back end arrays) soon after some processing - at the end of didSelectRowAtIndexPath. The arrays I use are listContent and filteredListContent - as per the Apple example.
My issue is, while in search mode, I remove a row using:
[self.filteredListContent removeObjectAtIndex: self.searchDisplayController.searchResultsTableView.indexPathForSelectedRow.row]
However, at the same time, I also want to remove the same object from self.listContent because when I return to non-search mode, that row should not appear.
I saw that self.tableView.indexPathForSelectedRow.row does not update regularly while in search results view. Instead, it gives the last selected row before I entered the search results view.
Off course, I can put some content into my array objects so that both indexes can be cross-referenced. But is there any efficient solution other than that? I think table view should have this mechanism.
And yes, I already do following in my viewWillAppear:
[self.tableView deselectRowAtIndexPath:self.tableView.indexPathForSelectedRow animated:YES];
This is working fine for me...
#pragma mark - delete row
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
if(tableView == self.searchDisplayController.searchResultsTableView)
// searching mode
{
// find row (index) from listContent
arrayObject = [filteredlistContent objectAtIndex:indexPath.row];
NSUInteger fooIndex = [listContent indexOfObject: arrayObject];
NSLog(#"index listContent %u", fooIndex);
//remove from listContent
[self.listContent removeObjectAtIndex:fooIndex];
[self.tableView reloadData];
//remove from filteredlistContent
[self.filteredlistContent removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else // tableView mode
{
[self.listContent removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
}
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.
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 having a problem that I see a lot of people having... however none of the fixes are working for me. But I did notice something odd happening when I put NSLog commands in the code.
I have the standard delete method:
- (void) tableView: (UITableView *) tableView commitEditingStyle: (UITableViewCellEditingStyle) editingStyle forRowAtIndexPath: (NSIndexPath *) indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.recipes removeObjectAtIndex: indexPath.row];
[tableView beginUpdates];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject: indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
}
}
recipes is the array that holds the data source.
Theoretically this should work just fine, but I get the error:
invalid number of rows in section 1. The number of rows contained in an existing section after the update (9) 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, 0 deleted).
But I know where this is falling apart, when I add an NSLog into the numberOfRowsInSection, I see that the method is being called twice from the method above.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
NSLog(#"THIS CALLED TWICE %i",[recipes count] );
return [recipes count];
}
Anyone know what else could cause the numberOfRowsInSection method to fire twice?
Thank you for your time.
After writing this, I saw that I had the following:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 2;
}
Apparently, numberOfRowsInSection is called for each section... changing the code to:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
Fixed the issue.