我开始在iOS13上收到警告(如下)。我注意到此警告弹出是因为UITableView
的窗口为空(选择了另一个选项卡,在选择表时按了详细 View Controller ...)。
我正在尝试从UITableView
代理更新NSFetchedResultController
。在iO13上执行此操作以保持表更新的正确方法是什么?
下面的代码在以前的版本中工作正常。
PS:任何一种beginUpdates
,reloadRowsAtIndexPaths:withRowAnimation:
,insertSections:withRowAnimation:
,endUpdates
都会导致此警告。
PS:我尝试重新加载表格,但是如果我向后导航,则会丢失动画以取消选择行(清除行选择)。
2019-09-27 09:40:42.849128+0200 xxx[63595:9762090] [TableView] Warning once only: UITableView was told to layout its visible cells and other contents without being in the view hierarchy (the table view or one of its superviews has not been added to a window). This may cause bugs by forcing views inside the table view to load and perform layout without accurate information (e.g. table view bounds, trait collection, layout margins, safe area insets, etc), and will also cause unnecessary performance overhead due to extra layout passes. Make a symbolic breakpoint at UITableViewAlertForLayoutOutsideViewHierarchy to catch this in the debugger and see what caused this to occur, so you can avoid this action altogether if possible, or defer it until the table view has been added to a window. Table view: ; layer = ; contentOffset: {0, -64}; contentSize: {375, 3432}; adjustedContentInset: {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];
// }
}
最佳答案
PS: Any kind of beginUpdates , reloadRowsAtIndexPaths:withRowAnimation: , insertSections:withRowAnimation: , endUpdates will cause this warning.
我发现将表更新包装在dispatch_async中断点触发的位置可以消除此问题:
dispatch_async(dispatch_get_main_queue(), ^(void){
[self.table reloadSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:UITableViewRowAnimationFade];
});
(可能必须走到调用堆栈中才能在中断时找到调用)
关于ios - UITableView没有窗口iOS13时的UITableViewAlertForLayoutOutsideViewHierarchy,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58130124/