UITableView没有窗口iOS13时的UITableViewAlertForLayoutOutsideViewHierarchy [英] UITableViewAlertForLayoutOutsideViewHierarchy when UITableView doesn't have window iOS13

查看:223
本文介绍了UITableView没有窗口iOS13时的UITableViewAlertForLayoutOutsideViewHierarchy的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始在iOS13上收到警告(如下).我注意到此警告弹出是因为 UITableView 的窗口为空(已选择另一个选项卡,在选择表时已推送详细视图控制器...).我正在尝试从 NSFetchedResultController 委托更新 UITableView .在iO13上执行此操作以保持表更新的正确方法是什么?

I started to receive warning (below) on iOS13. I have noticed that this warning pops up because UITableView's window is null (another tab is selected, pushed detailed view controller on table selection...). I am trying to update UITableView from NSFetchedResultController delegate. What is the correct way to do this on iO13 to keep table updated?

下面的代码在以前的版本中工作正常.

Code below worked fine on previous releases.

PS:任何类型的 beginUpdates reloadRowsAtIndexPaths:withRowAnimation: insertSections:withRowAnimation: endUpdates 导致此警告.

PS: Any kind of beginUpdates , reloadRowsAtIndexPaths:withRowAnimation: , insertSections:withRowAnimation: , endUpdates will cause this warning.

PS:我尝试重新加载表格,但是如果我向后导航,则会丢失动画以取消选择行(清除行选择).

PS: I tried reload table but if I navigate back I lose animation to deselect row (clear row selection).

2019-09-27 09:40:42.849128 + 0200 xxx [63595:9762090] [TableView]警告仅一次:通知UITableView布置其可见单元格和其他不属于视图层次结构(表视图或以下之一)的内容其超级视图尚未添加到窗口中).这可能会导致错误强制表格视图内的视图加载和执行布局而无需准确的信息(例如表格视图范围,特征收集,布局边距,安全区域插图等),并且还会导致不必要的由于额外的布局传递而导致的性能开销.象征性地UITableViewAlertForLayoutOutsideViewHierarchy的断点以捕获在调试器中查看此情况,并查看导致此情况发生的原因,因此您可以如果可能的话,请完全避免执行此操作,或者将其推迟到表格中视图已添加到窗口.表格视图:层=;contentOffset:{0,-64};contentSize:{375,3432};AdjustedContentInset:{64,0,0,0};dataSource:>

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:任何类型的beginUpdates,reloadRowsAtIndexPaths:withRowAnimation:,insertSections:withRowAnimation:,endUpdates都会导致此警告.

PS: Any kind of beginUpdates , reloadRowsAtIndexPaths:withRowAnimation: , insertSections:withRowAnimation: , endUpdates will cause this warning.

我发现将表更新包装到在dispatch_async中断点触发的位置可以消除此问题:

I found that wrapping the table update where the breakpoint triggers in dispatch_async eliminates the issue:

dispatch_async(dispatch_get_main_queue(), ^(void){
    [self.table reloadSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:UITableViewRowAnimationFade];
});

(可能必须走到调用堆栈中才能在中断时找到呼叫)

(may have to walk up the call stack to find the call when it breaks)

这篇关于UITableView没有窗口iOS13时的UITableViewAlertForLayoutOutsideViewHierarchy的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆