2

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.

Community
  • 1
  • 1
Cbas
  • 6,003
  • 11
  • 56
  • 87

1 Answers1

1

Try this

[self.tableView setContentOffset:newContentOffset animated:NO]
Tim007
  • 2,557
  • 1
  • 11
  • 20