6

私はUITabbarを持っていて、その中に複数のコントローラーがあります。コントローラの1つはコアデータにイベントを追加するために使用され、もう1つのコントローラはNSFetchedResultsControllerを使用してUITableViewのようにイベントを表示するために使用されます。コントローラが消えるとNSFetchedResultsControllerがtableviewを更新しないようにする方法は?

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

私がそれのようになり期待どおりに動作するようには思えないよう、私は、私はこの動作を達成することができますどのように思ったんだけど:

私はviewWillDisappearにnilにNSFetchedResultsControllerのデリゲートを設定し、それを復元していますへのコールとともに、viewWillAppearにあります。

どういうわけか、私は新しいデータを見て、これはそれがデリゲートを持っていない場合NSFetchedResultsControllerはフェッチが停止方法が原因である疑いはありません。

どのように私はきちんとそれが消えるUITableViewへの更新を「サスペンド」、それでもコントローラが再表示されたときにデータセット全体を見ることができますか?

答えて

7

NSFetchedResultsControllerのオブジェクトを設定してみてください。

1

は代わりにviewWillDisappearにnilにNSFetchedResultsControllerdelegateを設定するので、あなたがselfに戻ってそのデリゲートを設定した後viewWillAppear:NSFetchedResultsControllerperformFetch:を送信してみnilの

+0

なぜdownvote知って良いのだろうか? – user427969

2

テーブルビューの更新を「中断」する必要はないと思います。いずれにしても セルのデータのみを要求します。テーブルビューが表示されていない場合、更新は実行されません。

他のコントローラからのイベントを挿入するのに実際に時間がかかりますか?疑わしい。 Instrumentsは何を言いますか?

あなたのデリゲートメソッドが起動された場合は、テーブルビューは、すべてのアップデートを行う前に表示されている場合、あなたはまだチェックできます。

その後、robによって提案されたとおりに正確に行います。performFetch:viewWillAppear:になります。

+1

実際のUI更新がなくても、「controllerWillChangeContent」の 'beginUpdates'と' controllerDidChangeContent'の 'endUpdates'はしばらくFRCスレッドをフリーズしています。 –

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]; 
    } 
} 
関連する問題