views:

2128

answers:

1

I am performing a deletion of several rows of a table. In fact, on this occasion all visible cells are in fact deleted.

This causes the cell immediately below the visible frame to become visible after the animation, since all cells above it are now gone.

Here is the issue, this cell is also deleted. So I get the following error, I assume, because the tableview wants me to delete a cell that isn't on screen. (but WILL be on screen during/after the animation).

2009-06-15 17:44:30.114 HSS[18175:20b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 4.  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).'
2009-06-15 17:44:30.117 HSS[18175:20b] Stack: (
    807902715,
    2429263419,
    807986683,
    811271572,
    815059595,
    815007323,
    97367,
    96328,
    96282,
    810768858,
    807687328,
    807683624,
    839142449,
    839142646,
    814752238,
    10968,
    10822
)

So what do I do in this situation?

Code that causes exception follows. Note that I actually create a new array called "filteredTableGroups" in another method. This is the updated model. "allTableGroups" is every Cell Controller. Each cell controller contains a dictionary used to populate it's cells data. I use a key, "filteredDataSet", to determine whether a cell should remain in the filtered table. During the tableview cell deletion, I swap tableGroups to point to the updated model. (I am created my code similar to Matt Gallagher and Craig Hockenberry's solution of using Cell Controller's to control individual cells)

- (void)collapseVisableCells{

NSMutableArray *cellsToRemove = [NSMutableArray array];

for(NSArray *sections in self.allTableGroups){

    for(ScheduleCellController *cellController in sections){

        NSString *shouldDisplayString = (NSString*)[[cellController model] objectForKey:@"filteredDataSet"];

        BOOL shouldDisplay = [shouldDisplayString boolValue];

        if(!shouldDisplay){

            UITableViewCell *theCell = [cellController myCell];

            NSIndexPath *cellPath = [self.tableView indexPathForCell:theCell];
            NSLog([cellPath description]);

            if(cellPath!=nil)
                [cellsToRemove addObject:cellPath];


        }
    }

}



[self.tableView beginUpdates];
tableGroups = self.filteredTableGroups;
[self.tableView deleteRowsAtIndexPaths:cellsToRemove withRowAnimation:UITableViewRowAnimationTop];
[self.tableView endUpdates];

}

+2  A: 

I am not sure I have understood correctly what you mean, but you can try the following.

NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet];

Each time you delete an object from your model array related to a specific section of the tableView, check if the array count is zero, in which case add an index representing the section to indexes:

[array removeObjectAtIndex:indexPath.row];
if(![array count])
    [indexes addIndex: indexPath.section];

Determine all of the indexPaths related to the rows to be deleted, then update the tableView as follows:

[tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];
[tableView deleteSections:indexes withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];

Let me know if this works for you.

unforgiven
I will try to remove "dead sections" and see if that fixes my problem. It's hard to explain the issue. The main problem is that I can't delete cells that are off screen, but then the tableview complains that I didn't delete a cell that IS offscreen. Removing the entire section may work to remedy this situation. But I wouldn't call this expected behavior.
Corey Floyd
This worked. By deleting the empty sections, I was able to get around the problem. Not that I should be displaying empty sections. It was rather tedious to keep track of the sections to delete, but it worked great. Thanks.
Corey Floyd