Mise à jour
J'ai publié ma solution à ce problème sous forme de réponse ci-dessous. Elle adopte une approche différente de ma première révision.
Question originale J'ai déjà posé une question sur SO qui, selon moi, a résolu mes problèmes :
Cependant, je rencontre à nouveau des problèmes similaires lorsque je supprime des sections d'un UITableView. (ils ont refait surface lorsque j'ai fait varier le nombre de sections/rangs dans le tableau).
Avant que je ne vous perde à cause de la longueur de mon message, laissez-moi énoncer clairement le problème, et vous pourrez lire autant que vous le souhaitez pour y répondre.
Problème :
Si l'on supprime par lots des lignes ET des sections d'une UITableView, l'application se bloque, parfois. Cela dépend de la configuration de la table et de la combinaison de lignes et de sections que je choisis de supprimer.
Le journal indique que je me suis écrasé parce que je n'ai pas mis à jour la source de données et la table correctement :
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).
Maintenant, rapidement, avant que vous n'écriviez la réponse évidente, je vous assure que j'ai bien ajouté et supprimé les lignes et les sections correctement de la source de données. L'explication est longue, mais vous la trouverez ci-dessous, en suivant la méthode.
Donc avec ça, si vous êtes toujours intéressés
Méthode qui gère la suppression des sections et des rangées :
- (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;
}
A mon avis :
Le problème semble être le suivant : Si vous regardez ci-dessus où j'énumère le nombre de cellules dans chaque section, vous verrez que la section 5 semble augmenter de 1. Cependant, ce n'est pas vrai. La section 5 originale a en fait été supprimée et une autre section a pris sa place (plus précisément, il s'agit de l'ancienne section 10).
Alors pourquoi la vue de la table ne semble-t-elle pas s'en rendre compte ? Il devrait SAVOIR que j'ai supprimé l'ancienne section et ne doit pas s'attendre à ce qu'une nouvelle section, qui se trouve maintenant à l'index de l'ancienne section, soit liée par le nombre de lignes de la section supprimée.
J'espère que cela a un sens, c'est un peu compliqué d'écrire tout cela.
(Notez que ce code fonctionnait auparavant avec un nombre différent de lignes/sections. Cette configuration particulière semble lui poser des problèmes).