Remembering scroll position on UITableView

Deadly 提交于 2019-11-27 19:01:38

See here you have to first save the scrolled position of tableView i.e. contentOffset of tableView and then reuse it when you are coming back to tableView.

1)When and where you will save it :

When : At the point, when you are drilling down to detailViewController save the contentOffset of tableView

How : float verticalContentOffset = tableView.contentOffset.y;

2) How will you set tableView back to the same scrolled position :

[tableView setContentOffset:CGPointMake(0, verticalContentOffset)];

Hope this will help you.

Sorted!

With a bit of inspiration from Desdenova, whilst at work I had a good think about it and realised what it could be. Remembering that I had a search bar, I had implemented the following code a few months ago to hide it:

[self.tableView setContentOffset:CGPointMake(0,-20) animated:NO];

In naivety I put that in viewDidAppear rather than viewDidLoad. Obviously, this did hide the search bar, but with it being in the wrong void command it did it every time the masterDetailView returned to the top of the stack. So, after moving the above code to viewDidLoad it now still hides it, but only the once.

I'm just spelling it out like this for other beginners, like myself, who may come across the same problem and may just save their sanity!

Thanks to you all for your ideas that helped me out.

+1 to you all!

If anyone is wondering, I tried the solution by Prashant N and it worked. However reloadData don't actually reset the scroll position anymore now, so I didn't have to do anything other than reloadData.

My solution to this problem consisted in scrolling the table to the indexrow of the last item.

private func scrollToItem(item:Int, section:Int bottom:Bool = true, animated:Bool = false) {
    let indexPath = NSIndexPath(forRow: item:Int-1, inSection: section)
    var position = UITableViewScrollPosition.Bottom
    if (!bottom) { position = UITableViewScrollPosition.Top }
    self.tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: position, animated: animated)
}

For some reason this was halfway working for me (sometimes the position would only be approximate). I finally used the following a priori less clean solution

NSIndexPath *firstVisibleIndexPath = [[self.tableView indexPathsForVisibleRows] objectAtIndex:0];
[self.tableView scrollToRowAtIndexPath:self.firstVisibleIndexPath atScrollPosition:UITableViewScrollPositionTop animated:NO];
self.firstVisibleIndexPath = firstVisibleIndexPath;

which worked better.

As mentioned in other comments, scrolling to the top on Back navigation in a UINavigationController is not the default behavior.

Another cause might be that you are setting a cell near the top of the table as first responder in viewWillAppear, e.g. a search box or edit field near the top of your table. UITableViewController will scroll a first responder into view automatically, which is nice. As long as that's what you're trying to do. :) Take care to not set first responder in viewWillAppear unless that's what you want. Cheers, AZ

Dmitry Malysh

My decision for a collection:

CGFloat oldCollectionViewHeight = self.messageCollectionView.contentSize.height;

[self.messageCollectionView reloadData];
[self.messageCollectionView layoutIfNeeded];

CGFloat newCollectionViewHeight = self.messageCollectionView.contentSize.height;

if (oldCollectionViewHeight) {
    self.messageCollectionView.contentOffset = CGPointMake(0, newCollectionViewHeight - oldCollectionViewHeight);
}

For the table, the principle is the same.

You don’t need to do anything, while you are in the same view controller, your position will be the same. I’m afraid that somewhere in your view controller is being called a reloadData. Search for some method calling scrollToRowAtIndexPath.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!