Reputation: 10779
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
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
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