I have a tableView with one section in it which contains an array of values. Here is what the numberOfRowsInSection looks like
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
#warning Incomplete method implementation.
// Return the number of rows in the section.
return [allPasses count];
}
When you delete a row this code runs
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
[allPasses removeObjectAtIndex:indexPath.row];
// Delete the row from the data source
PassWhizEntity *passToRemove = self.allPasses[indexPath.row];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
// Get the local context
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];
[passToRemove MR_deleteInContext:localContext];
[localContext MR_save];
}
This works great and you can delete any rows but when you delete the last row the app crashes and you get this error.
Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'
But I don't know how to fix this. I am sure its quite a simple fix but I have tried adding one to the array and I'm not sure what else to do. Any ideas would be appreciated!
It doesn't work properly because these lines are in the wrong order:
[allPasses removeObjectAtIndex:indexPath.row];
// Delete the row from the data source
PassWhizEntity *passToRemove = self.allPasses[indexPath.row];
all you have at the moment is a hidden issue until you get to the last item.
Reverse the order of those lines so that you get the item to delete before you remove it from the array.
Related
I have implemented the tableView:editActionsForRowAtIndexPath: function, however i experience intermittently the indexPath passed to this function is nil. When i try to access indexPath.row , its get a value 18446744073709551615.
I am querying for the object in the array I use to build the table. and getting the crash --[__NSArrayM objectAtIndex:]: index 18446744073709551615 beyond bounds [0 .. 1]'
There was a case where I was reloading my table using [table reloadData] an editAction call then would get passed a nil indexPath, however this is still intermittently happening.
Is there any way i can enforce the correct indexPath to be passed to tableView:editActionsForRowAtIndexPath:
You have to implement this - (void)tableView:(UITableView *)tableView commitEditingStyle method where data array need to be adjusted.
For details look at this article Inserting and Deleting Rows and Sections
You can handle this by removing the item corresponding to
the row from data array at first and then sending deleteRowsAtIndexPaths:withRowAnimation: to the table view.
Try to insert below lines of code inside - (void)tableView:(UITableView *)tableView commitEditingStyle method:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if ( editingStyle== UITableViewCellEditingStyleDelete) {
// remove item from array at first
[dataArray removeObjectAtIndex:indexPath.row];
// then delete table row from tableview
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
Hope it will work!
I have a UITableViewController set up that displays my managedObjects properly when it's loaded, however when I go to delete a cell my app crashes. This is what the console has to say:
2015-05-03 09:55:20.125 MyApp[9461:663817] *** 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).'
When I reboot the app and go to my TVC, the object that I deleted the last time is deleted.
I have sections set up in my NSFetchedResultsController that is instantiated when viewDidLoad is called. I suspect I have a small issue, but I'm not sure where to go to add the missing line(s?).
I enable swipe to delete in viewDidLoad with this line:
// Enable swipe to delete
self.tableView.allowsMultipleSelectionDuringEditing = NO;
Here's my commitEditingStyle:
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete selected NSManagedObject from managedObjectContext
NSManagedObject *objectToDelete = [self.fetchedResultsController objectAtIndexPath:indexPath];
[self.managedObjectContext deleteObject:objectToDelete];
[self.managedObjectContext save:nil];
// Delete the row from the data source
[tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
} 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
}
}
Thank you for reading. If you have any ideas, I welcome them.
The error message is saying that number of row returns from numberOfRowInSection is not matching with current number of item in table..
when you use fetchedResultsController numberOfRowsInSection should look something like this.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [[self.fetchedResultsController fetchedObjects] count];
}
and fetchedResultsController delegate didChangeObject: is then called automatically which calls the deleteRowAtIndexPaths: inside.. so you don't need to call the deleteRowAtIndexPaths: just call deleteObject, otherwise it deletes twice.
I have some problem with deleting rows from a tableView which is filled with coreData objects.
Trying to do this:
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath*)indexPath{
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.tableView beginUpdates];
NSManagedObject *managedObject = [self.fetchedResultsController objectAtIndexPath:indexPath];
NSLog(#"Deleting (%#)", [managedObject valueForKey:#"original_title"]);
[self.managedObjectContext deleteObject:managedObject];
[self.managedObjectContext save:nil];
[self performFetch];
[self.tableView endUpdates];
}
}
So, when I click the "Delete" button, the app crashes with the following Log:
*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-2872.3/UITableView.m:1254
2013-08-13 18:39:17.624 RR_proto[1076:a0b] *** Terminating app due to uncaught exception
'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of sections.
The number of sections contained in the table view after the update (1) must be equal
to the number of sections contained in the table view before the update (2), plus or minus
the number of sections inserted or deleted (0 inserted, 0 deleted).'
*** First throw call stack:
I also tried to add the following line after [self.managedObjectContext save:nil]:
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
But the app crashes like before.
One more thing, everytime i start the app again after a crash through delete-action, the cell which should be deleted is really gone!
Would be very nice, if somebody can help.
I know there are many questions about similar problems and I tried different things from these, without success.
Thanks!
The table view is updated automatically by the fetched results controller delegate
methods when objects are added, deleted or modified.
Therefore, to remove an object, just delete it from the managed object context.
Don't call beginUpdates, endUpdates, deleteRowsAtIndexPaths or performFetch:
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath*)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSManagedObject *managedObject = [self.fetchedResultsController objectAtIndexPath:indexPath];
[self.managedObjectContext deleteObject:managedObject];
[self.managedObjectContext save:nil];
}
}
Hi the following function doesn´t work for me and i don´t get why....
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
// Delete the row from the data source
NSString *selectedCategory = [self.daten objectAtIndex:indexPath.row];
[self.daten removeObjectAtIndex:indexPath.row]; //we assume, that mySourceArray is a NSMutableArray we use as our data source
[self.tableView beginUpdates];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];
// ...
}
}
I don´t have any Sections...I always get that exception:
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 (19) must be equal to the number of rows contained in that section before the update (19), 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).'
* First throw call stack:
(0x342692a3 0x33a3b97f 0x3426915d 0x3922e2af 0x36dd5b83 0x5453d 0x36f6b5d9 0x36e8c0ad 0x36e8c05f 0x36e8c03d 0x36e8b8f3 0x36e8c0ad 0x36e8c05f 0x36e8c03d 0x36e8b8f3 0x36e8bde9 0x36db45f9 0x36da1809 0x36da1123 0x34f195a3 0x34f191d3 0x3423e173 0x3423e117 0x3423cf99 0x341afebd 0x341afd49 0x34f182eb 0x36df5301 0x24343 0x38e34b20)
libc++abi.dylib: terminate called throwing an exception
You need to update your number of rows in numberOfRowsInSection: method. As i can see, you need to return your [self.daten count] in this method.
As its told, the system checks this number before/after update/delete to keep data integrity.
You always have a section :)
Implement it like this:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.daten count];
}
Also, remember that you need to set both UITableViewDelegate and UITableViewDataSource to self.
OK, the problem is: NSMutableArray's removeObjectAtIndex: method does not resize it. So you have to handle it by yourself. Create new array with right capacity and move the rest of elements to it. You can google how to resize NSMutableArray.
I am having a crash with deleting a cell from a tableview. I am using a NSMutableArray loaded from NSUserDefaults to load the cells into the tableview.
This is the crash:
Code:
2011-09-03 18:21:06.097 App[10356:707] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit/UIKit-1906/UITableView.m:1046
2011-09-03 18:21:06.100 App[10356: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 (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).'
This is how I delete the rows...
Code:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
[self.cellArray objectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSMutableArray arrayWithObject:indexPath] withRowAnimation:YES];
[[NSUserDefaults standardUserDefaults] setObject:cellArray forKey:#"cellArray"];
}
This is my numberOfRowsInSection delegate method:
Code:
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
self.cellArray = [NSMutableArray array];
[self.cellArray addObjectsFromArray:[[NSUserDefaults standardUserDefaults] objectForKey:#"cellArray"]];
if ([self.cellArray count] == 0) {
[ivstatstableView setHidden:YES];
[sortbar setEnabled:NO];
}
return [cellArray count];
}
Any idea what is wrong here?
You need to call reloadData after removing an object from your array. When you call reloadData method, your new array is updated which lets your UITableView load new cells based on the new updated data.