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