Reputation: 21
I have a UITableView that receives its data from an NSFetchedResultsController. The NSFetchedResultsController's data is updated occasionally by network calls. After each time the data is updated from the network call, I update the UITableView with [tableView reloadData] in order to add any new items.
Part of my UI also enables cells to be repositioned horizontally. I would like these cells to not be re-positioned each time the table's data is refreshed, but unfortunately, [tableview reloadData] does just that.
What is the ideal way to update the data in a tableview without repositioning it's rows? Should I override the tableview's reloadData method and do something fancy there or perhaps override the tableview cells layoutSubviews method?
I position the cell like so:
CGRect newFrame = cell.frame;
newFrame.origin.x = -cell.frame.size.width;
cell.frame = newFrame;
After the NSFetched Results Controller receives more data from the network call, it calls it's delegate's method:
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.eventTableView reloadData];
}
Which calls tableview: cellForRowAtIndexPath: and the cell that is returned from the dequeue has it's origin at (0,0)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"EventCell";
EventCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
[cellNib instantiateWithOwner:self options:nil];
cell = self.customCell;
}
// Configure the cell...
Event *event = [fetchedResultsController objectAtIndexPath:indexPath];
[cell configureCellWithEvent:event];
return cell;
}
Upvotes: 2
Views: 805
Reputation: 857
You might try the UITableViewDelegate method tableView:willDisplayCell:forRowAtIndexPath:
, which is invoked just before any cell is added to the table view or scrolls into the table's visible area. In there, you can position the cell if needed, and this will work after reloading.
This isn't essential to your question, but I'd also suggest changing the cell's transform property instead of its frame. That way you can't accidentally move it farther than you want it to go (say if you shift it twice).
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
//Determine if the cell should be shifted.
if (cellShouldShift) {
cell.transform = CGAffineTransformMakeTranslation(0 - cell.bounds.size.width, 0);
} else {
cell.transform = CGAffineTransformIdentity;
}
}
Upvotes: 0