更新刪除部分的UITableView:動畫
我已經發布我解決這個問題,如下回答。它採用了與我的第一次修訂不同的方法。
原始的問題 我以前問的SO一個問題,我認爲解決我的問題:
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).
現在很快,你寫明顯的答案之前,我向你保證我的確添加並刪除了行和部分正確地來自dataSource。解釋是漫長的,但你會在下面找到它,遵循這個方法。
所以用的是,如果你仍然有興趣...
方法處理去除部分和行:
- (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部分)。
那麼爲什麼表格視圖似乎沒有意識到這一點?它應該知道我刪除了舊部分和不應該期望現在位於舊部分索引處的新部分受到刪除部分行數的限制。
希望這是有道理的,這寫出來有點複雜。
(請注意,此代碼之前使用不同數量的行/部分工作。這種特定的配置似乎給它的問題)
或者,跟蹤您需要擺脫的每個單元格的indexPath,並在您執行刪除操作時適當調整它們。 (這可能是漫長的/令人費解的/不恰當的方式 - 只是一個念頭。) – Tim 2009-07-02 04:07:48