Обновление
Я отправил свое решение этой проблемы в качестве ответа ниже. Это отличается от моей первой ревизии.
Оригинальный вопрос
Ранее я задавал вопрос о SO, который, как я думал, решил мои проблемы:
Как работать с невидимыми строками во время удаления строки. (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).
Так почему табличное представление не осознает этого? Следует знать, что я удалил старый раздел и , и не следует ожидать, что новый раздел, который теперь расположен по индексу старого раздела, будет связан с количеством строк в удаленном разделе.
Надеюсь, это имеет смысл, это немного сложно записать.
(обратите внимание, что этот код работал раньше с другим количеством строк / разделов. Эта конкретная конфигурация, похоже, создает проблемы)