6

我有一個UITabbar其中有多個控制器。其中一個控制器用於將事件添加到核心數據,而另一個控制器則用於使用NSFetchedResultsController在UITableView中顯示事件。如何防止控制器消失時NSFetchedResultsController更新tableview?

以下是我想實現的行爲: 消失後,UITableView停止更新,並且當用戶返回時,整個表視圖都會重新加載。否則,從其他控制器插入事件需要更長時間,因爲在UITableView中創建了新行,甚至認爲它不可見。

我不知道我怎麼能做到這一點的行爲,因爲它似乎並不如我所料這將是工作:

我已經設置了NSFetchedResultsController的先nil代表在viewWillDisappear,並恢復它在viewWillAppear中,同時致電[UITableView reloadData];

不知怎的,我沒有看到新的數據,並且懷疑這是因爲,如果它不具有委託NSFetchedResultsController停止抓取的方式。

我怎樣才能正確地「暫停」更新UITableView,當它消失了,但還是能看到整個數據集時,控制器會再次出現?

回答

7

嘗試在viewWillAppear:發送performFetch:NSFetchedResultsController已設置其委託回self後。

1

而是在viewWillDisappearNSFetchedResultsControllerdelegate設置爲無,儘量的NSFetchedResultsController對象設置爲nil,

+0

這將是一件好事知道爲什麼downvote? – user427969

2

我覺得你不必爲「暫停」的表視圖更新。無論如何,UITableView只會請求來自NSFetchedResultsController可見的單元的數據。如果表視圖不可見,則不會觸發更新。

你測試,如果從另一個控制器插入事件真的需要更長的時間?我對此表示懷疑。儀器說什麼?

如果你的委託方法被解僱,你仍然可以檢查表視圖做任何更新前可見。

之後,您完全按照rob的建議進行操作:在viewWillAppear:中做一個performFetch:

+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]; 
    } 
} 
相關問題