7

私はUITabbarそれに複数のコントローラを持っています。コントローラーの 1 つはコア データにイベントを追加するために使用され、別のコントローラーは を使用して UITableView のようにイベントを表示するために使用されますNSFetchedResultsController

私が達成したい動作は次のとおりです。消えると、UITableView は更新を停止し、ユーザーが戻ってくると、テーブル ビュー全体が再読み込みされます。そうしないと、他のコントローラーからイベントを挿入すると、表示されていなくても に新しい行が作成されるため、時間がかかりUITableViewます。

期待どおりに機能しないように見えるため、この動作をどのように達成できるか疑問に思っています。

NSFetchedResultsController のデリゲートを で nil に設定し、への呼び出しとともに でviewWillDisappear復元しました。viewWillAppear[UITableView reloadData]

どういうわけか、新しいデータが表示されません。これは、デリゲートがない場合に NSFetchedResultsController がフェッチを停止する方法が原因であると思われます。

UITableView更新が消えたときに更新を適切に「一時停止」し、コントローラーが再表示されたときにデータセット全体を表示するにはどうすればよいですか?

4

4 に答える 4

7

デリゲートを に戻してから、に送信performFetch:してみてください。NSFetchedResultsControllerviewWillAppear:self

于 2012-11-02T00:09:07.947 に答える
2

テーブルビューの更新を「一時停止」する必要はないと思います。AUITableViewはとにかくNSFetchedResultsController可視セルの からのデータのみを要求します。テーブル ビューが表示されていない場合、更新は発生しません。

別のコントローラーからのイベントの挿入に実際に時間がかかるかどうかをテストしましたか? 疑わしい。楽器は何と言っていますか?

デリゲート メソッドが起動された場合でも、更新を行う前にテーブル ビューが表示されているかどうかを確認できます。

その後、rob が提案したとおりに実行しperformFetch:ますviewWillAppear:

于 2012-11-02T11:37:17.000 に答える
0

delegateNSFetchedResultsControllerを nil に設定する代わりにviewWillDisappear、 のオブジェクトNSFetchedResultsControllerを nilに設定してみてください

于 2012-11-02T00:06:50.113 に答える
0

この大雑把なアプローチはどうですか?テストしていません。

@property (nonatomic) BOOL bruteForceReload;

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    self.bruteForceReload = NO;
}

-(void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    self.bruteForceReload = YES;
}

-(void)setBruteForceReload:(BOOL)bruteForceReload {
    _bruteForceReload = bruteForceReload;
    if (_bruteForceReload) {
        [self.tableView reloadData];
    }
}

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
    if (!self.bruteForceReload) {
        [self.tableView beginUpdates];
    }
}

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
           atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
    if (!self.bruteForceReload) {
        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
{
    if (!self.bruteForceReload) {
        UITableView *tableView = self.tableView;

        switch(type) {
            case NSFetchedResultsChangeInsert:
                [tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;

            case NSFetchedResultsChangeDelete:
                [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;

            case NSFetchedResultsChangeUpdate:
                [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
                break;

            case NSFetchedResultsChangeMove:
                [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
                [tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;
        }
    }
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    if (!self.bruteForceReload) {
        [self.tableView endUpdates];
    } else {
        [self.tableView reloadData];
    }
}
于 2015-09-30T16:53:46.567 に答える