jdog
jdog

Reputation: 10779

UITableViewCells are flickering when tableview first loads

So I have a UITabelView using custom UITableViewCells. I chased down the issue and its in this method "controllerDidChangeContent", which is getting called about 5 times as the table loads. This method is being called because of Core Data updates.

I can stop the flickering from happening if I comment out either line that has <--- pointing at it. I am sure we do NOT want to comment out the [self reloadData] as that refreshes the data when Core Data is changed. But I am not so sure if endUpdates is ok to comment out?

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

However, if I comment out the endUpdates line then all the table data is NOT getting written to the UITableView. There is a couple cells missing.

I am thinking the issue isn't this method or its inner methods, but rather how the cell content is being drawn?

Upvotes: 0

Views: 1157

Answers (2)

Zoeb S
Zoeb S

Reputation: 705

Why don't you simply call reloadSections method instead of [self.tableView reloadData];

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

Upvotes: 0

random
random

Reputation: 8608

You should not need to call reloadData after the endUpdates. You make changes to your UITableView data source within the beginUpdates endUpdates block so that you don't have to call reloadData. You call reloadData if your entire data source has changed because it can be relatively expensive call. Using beginUpdates and endUpdates gives you the ability to change/insert/delete an item from your data source without reloading the entire UITableView.

Here is what it should look like (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];
}

If this does not help solve your problem then I will need to see more code, specifically where you are performing the data source updates within the beginUpdates and endUpdates block.

Upvotes: 3

Related Questions