J'ai commencé à recevoir un avertissement (ci-dessous) sur iOS13. J'ai remarqué que cet avertissement apparaît parce que la fenêtre UITableView
est NULL (un autre onglet est sélectionné, poussé le contrôleur de vue détaillé sur la sélection de table ...). J'essaie de mettre à jour UITableView
de NSFetchedResultController
délégué. Quelle est la bonne façon de faire cela sur IO13 pour garder la table mise à jour?
Le code ci-dessous a fonctionné bien sur les versions précédentes.
PS: tout type de beginUpdates
, reloadRowsAtIndexPaths:withRowAnimation:
, insertSections:withRowAnimation:
, endUpdates
va causer cet avertissement.
PS: J'ai essayé de recharger la table, mais si je navigue en arrière, je perds une animation pour désélectionner la ligne (sélection de ligne claire).
2019-09-27 09: 40: 42.849128 + 0200 xxx [63595: 9762090] [TableView] Avertissement Une fois uniquement: UitailView a été invité à mettre en place ses cellules visibles et d'autres contenus sans être dans la hiérarchie de vue (la vue de la table ou l'une de ses Les SuperViews n'ont pas été ajoutés à une fenêtre). Cela peut provoquer des bugs en forçant les vues à l'intérieur de la vue de table pour charger et effectuer la mise en page sans informations précises (par exemple, les limites de la vue de table, la collecte de trait, les marges de mise en page, les embargons de sécurité, etc.) et entraîneront également une surcharge de performance inutile due à des passes de mise en page supplémentaires. . Fabriquez un point d'arrêt symbolique chez UitailViewAlertForlayOutOtViewHierarchy pour attraper cela dans le débogueur et voir ce que cela a provoqué cela. Vous pouvez donc éviter cette action si possible ou le refermer jusqu'à ce que la vue de la table ait été ajoutée à une fenêtre. Vue de tableau: ; couche =; contentoffset: {0, -64}; contentize: {375, 3432}; ajustéContenseSet: {64, 0, 0, 0}; DataSource:>
// ------------ ------------ ------------ ------------ ------------ ------------
#pragma mark - FetchedResultsController delegate
- (void) controllerWillChangeContent:(NSFetchedResultsController *)controller {
// if (self.tableView.window) {
[self.tableView beginUpdates];
// }
}
- (void) controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
if (type == NSFetchedResultsChangeInsert && newIndexPath != nil) {
[self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
if (type == NSFetchedResultsChangeUpdate && indexPath != nil) {
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
// id<CellLoadable> cell = [self.tableView cellForRowAtIndexPath:indexPath];
// [cell loadData:anObject];
}
if (type == NSFetchedResultsChangeMove && indexPath != nil && newIndexPath != nil) {
// if cell is visible, update it
id<CellLoadable> cell = [self.tableView cellForRowAtIndexPath:indexPath];
[cell loadData:anObject];
[self.tableView moveRowAtIndexPath:indexPath toIndexPath:newIndexPath];
}
}
- (void) controller:(NSFetchedResultsController *)controller didChangeSection:(id<NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
if (type == NSFetchedResultsChangeInsert) {
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
}
if (type == NSFetchedResultsChangeDelete) {
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
}
}
- (void) controllerDidChangeContent:(NSFetchedResultsController *)controller {
// if (self.tableView.window) {
[self.tableView endUpdates];
// }
}
Vous pouvez essayer le code ci-dessous, c'est-à-dire en vérifiant la fenêtre et en appelant Reloaderdata à la place. FYI Cela ne recharge pas réellement toutes les cellules qui appelle simplement le nombre de lignes, de sections, etc., puis sur l'apparition suivante, les nouvelles cellules seront chargées. Vous feriez mieux de désactiver le contrôleur d'extraction lorsque la vue disparaît et la rechargement du tableau suivante apparaît.
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
if(!self.tableView.window){
return;
}
[self.tableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
if(!self.tableView.window){
return;
}
switch(type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
default:
return;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath {
UITableView *tableView = self.tableView;
if(!tableView.window){
return;
}
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeMove:
[tableView moveRowAtIndexPath:indexPath toIndexPath:newIndexPath];
case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] withEvent:anObject];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
if(!self.tableView.window){
[self.tableView reloadData];
return;
}
[self.tableView endUpdates];
}
Remarque, vous pouvez également souhaiter resélectionner une cellule précédemment sélectionnée. Il y a quelques façons différentes de le faire.