web-dev-qa-db-ja.com

UitaiveViewAlertForLayOutOutSideViewHierarchy UitedViewにウィンドウios13がない場合

IOS13で警告(下記)を受け取り始めました。 UITableViewのウィンドウがNULLのためにこの警告が表示されていることに気付いた(別のタブが選択され、テーブルの選択に詳細なビューコントローラが表示されます)。 UITableViewNSFetchedResultController legateから更新しようとしています。テーブルを更新するためにIO13でこれを行う正しい方法は何ですか?

以下のコードは以前のリリースでうまく機能しました。

PS:あらゆる種類のbeginUpdatesreloadRowsAtIndexPaths:withRowAnimation:insertSections:withRowAnimation:endUpdatesはこの警告を引き起こします。

PS:テーブルをリロードしようとしましたが、戻って戻ると、アニメーションを失い、行の選択解除(行選択のクリア)。

2019-09-27 09:40:42.849128 + 0200 XXX [63595:9762090] [TableView]警告警告:UitaitViewは、表示されているセルやその他のコンテンツを表示階層(テーブルビューまたはその1つの1つ)に配置するように言われました。スーパービューはウィンドウに追加されていません)。これにより、テーブルビュー内のビューを強制することによってバグが発生して、正確な情報(テーブルビューの境界、特性コレクション、レイアウトマージン、安全なエリアインセットなど)がなく、追加のレイアウトパスのため、不要なパフォーマンスのオーバーヘッドも発生する可能性があります。 。 Debuggerでこれをキャッチするためにこれをキャッチし、これが発生した内容を確認するために、UITableViewAlertForLayoutOutSideViewHierarchyでシンボリックブレークポイントを作成し、これが発生した内容を確認してください。テーブルビュー:;レイヤー=; ContentOffSet:{0、-64}; Compentizize:{375,3432}; AdjustedContentInset:{64,0,0,0}。データソース:>

// ------------  ------------  ------------  ------------  ------------  ------------
#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];
//    }
}
 _
9
Marek H

以下のコードを試すことができます、すなわちウィンドウをチェックし、代わりにReloadDataを呼び出すことができます。 FYIこれは実際にすべてのセルをリロードしていません。ビューが消えるとフェッチコントローラを無効にし、次にテーブルが表示されます。

- (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];
}
 _

注意してください、あなたは以前に選択されたセルを再選択するのが好きかもしれません。それをするためのいくつかの異なる方法があります。

0
malhal