I have a UITableViewController
and when the user scrolls to the top, I want to add a bunch of cells above the first cell without affecting the current scroll position (just like iMessage)
I know I can use insertRowsAtIndexPaths
to do this without reloading the data, but I just want to do it the simplest way possible first. So I am overwriting the data and calling reload
, then calling setContentOffset
, but no matter what I set the offset to, the table always reverts to the top.
// in an NSNotification handler
//...
dispatch_async(dispatch_get_main_queue(), ^{
// get old content height
CGSize oldContentSize = self.tableView.contentSize;
NSLog(@"old content height: %f", oldContentSize.height);
// update tableView data
self.messages = updatedMessages;
[self.tableView reloadData];
// get new content height
CGSize newContentSize = self.tableView.contentSize;
NSLog(@"new content height: %f", newContentSize.height);
// move to user scroll position
CGPoint newContentOffset = CGPointMake(0, newContentSize.height - oldContentSize.height);
[self.tableView setContentOffset:newContentOffset];
});
When I run this I get:
old content height: 557.765625
new content height: 1249.050781
but the tableView reverts to the top instead of maintaining its scroll position.
I found that if I call [self.tableView setContentOffset:newContentOffset animated:YES];
It always scrolls down to the correct position, but the movement is unacceptable.
How can I maintain the scroll position after reloading the tableView data?
I've looked at these:
setContentOffset only works if animated is set to YES
UIScrollView setContentOffset: animated: not working
UITableView contentOffSet is not working properly
but their solutions don't work in my case.