当tableview首次加载时,UITableViewCells会闪烁

时间:2014-02-27 17:17:04

标签: ios objective-c uitableview

所以我有一个使用自定义UITableViewCells的UITabelView。我在这个方法“controllerDidChangeContent”中追查了这个问题,它在表加载时被调用了大约5次。由于核心数据更新,正在调用此方法。

如果我注释掉任何一个指向它的行,我就可以阻止闪烁的发生。我确信我们不想将[self reloadData]注释掉,因为当核心数据发生变化时会刷新数据。但我不确定endUpdates是否可以评论出来?

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
  [[self tableView] endUpdates]; <--
  [[self tableView] reloadData]; <-- 
  [UIView dismissIndicator];
}

但是,如果我注释掉endUpdates行,则所有表数据都不会写入UITableView。有几个细胞缺失。

我认为问题不在于这个方法或它的内部方法,而在于如何绘制单元格内容?

2 个答案:

答案 0 :(得分:3)

您不需要在reloadData之后致电endUpdates。您在UITableView beginUpdates块中对endUpdates数据源进行了更改,因此您无需致电reloadData。如果您的整个数据源已更改,则调用reloadData,因为它可能是相对昂贵的调用。使用beginUpdatesendUpdates,您可以在不重新加载整个UITableView的情况下更改/插入/删除数据源中的项目。

这应该是(taken from Ray Wenderlich tutorial)

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
    // The fetch controller is about to start sending change notifications, so prepare the table view for updates.
    [self.tableView beginUpdates];
}


- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {

    UITableView *tableView = self.tableView;

    switch(type) {

        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

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

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

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


- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id )sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {

    switch(type) {

        case NSFetchedResultsChangeInsert:
            [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}


- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    // The fetch controller has sent all current change notifications, so tell the table view to process all updates.
    [self.tableView endUpdates];
}

如果这无法解决您的问题,那么我需要查看更多代码,特别是您在beginUpdatesendUpdates块中执行数据源更新的位置。

答案 1 :(得分:0)

为什么不简单地调用reloadSections方法而不是[self.tableView reloadData];

[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationNone];