36
votes

I have lots of data and lots of rows in my tableView. when data changes I want to update my visible cells on the screen, I really don't want to use reloadData because it's an expensive call.

Is it possible to somehow update the visible cells only? I tried calling : beginUpdate & endUpdate on the table, but that doesn't work all the time?

Any suggestions?

3
Are you sure reloadData is expensive? I'd expect it to be quite cheap, as long as you're not using variable heights. It's going to query how many sections you have in the table, how many rows in each section, and purge its cache. But cells will be reloaded on demand, which means only the visible cells should be reloaded. - Steven Fisher
If you going to refresh all the visible cells then reloadData shouldn't be that expensive. - Nevin
@StevenFisher Yes in my case it's very expensive, I have lots of calculation, such as required height of the cells, and some web calls. So I probably should have said it's expensive for my case. - aryaxt
Yeah, if you're doing variable height cells, it's probably very expensive. Thanks for clarifying. :) - Steven Fisher

3 Answers

87
votes

You can:

[tableView reloadRowsAtIndexPaths:[tableView indexPathsForVisibleRows] 
                 withRowAnimation:UITableViewRowAnimationNone];
0
votes

For Swift 3:

tableView.reloadRows(at: tableView.indexPathsForVisibleRows!, with: .none)
-1
votes

Try calling 'deleteRowsAtIndexPaths', a method of UITableView, right after you delete the model from your data source. For example, if you are deleting a row in editing mode, you could write something like the code below. Note that the first line in the 'if' statement removes the object from the data source, and the second line cleans up the table:

-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{

    if ( editingStyle == UITableViewCellEditingStyleDelete ) {

         [[[[[ItemsStore sharedStore] parameterArray] objectAtIndex:indexPath.section]  objectForKey:@"data"] removeObjectAtIndex:indexPath.row];

        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];

    }
}