【发布时间】:2010-11-06 20:37:50
【问题描述】:
更新
我已经在下面发布了我对这个问题的解决方案作为答案。它采用了与我的第一次修订不同的方法。
原始问题 我之前问过一个我认为解决了我的问题的问题:
How to deal with non-visible rows during row deletion. (UITableViews)
但是,当我从 UITableView 中删除部分时,我现在又遇到了类似的问题。 (当我改变表格中的部分/行数时,它们重新出现)。
在因为我的帖子太长而失去你之前,让我清楚地说明问题,你可以阅读尽可能多的内容来提供答案。
问题:
如果从 UITableView 批量删除行和部分,应用程序有时会崩溃。这取决于表格的配置以及我选择删除的行和部分的组合。
日志说我崩溃了,因为它说我没有正确更新数据源和表:
Invalid update: invalid number of rows in section 5. 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, 0 deleted).
现在很快,在你写出明显的答案之前,我向你保证,我确实已经从数据源中正确地添加和删除了行和部分。解释很长,但你会在下面找到它,按照方法。
那么,如果你仍然感兴趣的话……
处理删除部分和行的方法:
- (void)createFilteredTableGroups{
//index set to hold sections to remove for deletion animation
NSMutableIndexSet *sectionsToDelete = [NSMutableIndexSet indexSet];
[sectionsToDelete removeIndex:0];
//array to track cells for deletion animation
NSMutableArray *cellsToDelete = [NSMutableArray array];
//array to track controllers to delete from presentation model
NSMutableArray *controllersToDelete = [NSMutableArray array];
//for each section
for(NSUInteger i=0; i<[tableGroups count];i++){
NSMutableArray *section = [tableGroups objectAtIndex:i];
//controllers to remove
NSMutableIndexSet *controllersToDeleteInCurrentSection = [NSMutableIndexSet indexSet];
[controllersToDeleteInCurrentSection removeIndex:0];
NSUInteger indexOfController = 0;
//for each cell controller
for(ScheduleCellController *cellController in section){
//bool indicating whether the cell controller's cell should be removed
NSString *shouldDisplayString = (NSString*)[[cellController model] objectForKey:@"filteredDataSet"];
BOOL shouldDisplay = [shouldDisplayString boolValue];
//if it should be removed
if(!shouldDisplay){
NSIndexPath *cellPath = [self indexPathOfCellWithCellController:cellController];
//if cell is on screen, mark for animated deletion
if(cellPath!=nil)
[cellsToDelete addObject:cellPath];
//marking controller for deleting from presentation model
[controllersToDeleteInCurrentSection addIndex:indexOfController];
}
indexOfController++;
}
//if removing all items in section, add section to removed in animation
if([controllersToDeleteInCurrentSection count]==[section count])
[sectionsToDelete addIndex:i];
[controllersToDelete addObject:controllersToDeleteInCurrentSection];
}
//copy the unfiltered data so we can remove the data that we want to filter out
NSMutableArray *newHeaders = [tableHeaders mutableCopy];
NSMutableArray *newTableGroups = [[allTableGroups mutableCopy] autorelease];
//removing controllers
int i = 0;
for(NSMutableArray *section in newTableGroups){
NSIndexSet *indexesToDelete = [controllersToDelete objectAtIndex:i];
[section removeObjectsAtIndexes:indexesToDelete];
i++;
}
//removing empty sections and cooresponding headers
[newHeaders removeObjectsAtIndexes:sectionsToDelete];
[newTableGroups removeObjectsAtIndexes:sectionsToDelete];
//update headers
[tableHeaders release];
tableHeaders = newHeaders;
//storing filtered table groups
self.filteredTableGroups = newTableGroups;
//filtering animation and presentation model update
[self.tableView beginUpdates];
tableGroups = self.filteredTableGroups;
[self.tableView deleteSections:sectionsToDelete withRowAnimation:UITableViewRowAnimationTop];
[self.tableView deleteRowsAtIndexPaths:cellsToDelete withRowAnimation:UITableViewRowAnimationTop];
[self.tableView endUpdates];
//marking table as filtered
self.tableIsFiltered = YES;
}
我的猜测:
问题似乎是这样的:如果您查看上面我列出每个部分中的单元格数量的位置,您会看到第 5 部分似乎增加了 1。但是,事实并非如此。原来的第 5 节实际上已被删除,取而代之的是另一个节(具体来说,它是旧的第 10 节)。
那么为什么表格视图似乎没有意识到这一点?它应该知道我删除了旧部分并且不应该期望现在位于旧部分索引处的新部分受已删除部分的行数的约束。
希望这是有道理的,写出来有点复杂。
(请注意,此代码之前使用不同数量的行/部分。此特定配置似乎给它带来了问题)
【问题讨论】:
标签: iphone cocoa-touch uitableview uikit