Reset scroll on UICollectionView

IphoneObjective CIpadIos6Uicollectionview

Iphone Problem Overview


I have a horizontal UICollectionView which works fine and scrolls. When I tap an item I update my data and call reloadData. This works and the new data is displayed in the UICollectionView. The problem is the scroll position doesn't change and it is still viewing the last place. I want to reset the scrolling to the top (Or left in my case). How can I do this?

Iphone Solutions


Solution 1 - Iphone

You want setContentOffset:. It takes a CGPoint as and argument that you can set to what ever you want using CGPointMake, but if you wish to return to the very beginning of the collection, you can simply use CGPointZero.

[collectionView setContentOffset:CGPointZero animated:YES];

Solution 2 - Iphone

You can use this method to scroll to any item you want:

- (void)scrollToItemAtIndexPath:(NSIndexPath *)indexPath 
               atScrollPosition:(UICollectionViewScrollPosition)scrollPosition 
                       animated:(BOOL)animated

Solution 3 - Iphone

I use this quite often in different parts of my app so I just extended UIScrollView so it can be used on any scroll view and scroll view subclass:

extension UIScrollView {        
    /// Sets content offset to the top.
    func resetScrollPositionToTop() {
        self.contentOffset = CGPoint(x: -contentInset.left, y: -contentInset.top)
    }
}

So whenever I need to reset the position:

self.collectionView.resetScrollPositionToTop()

Solution 4 - Iphone

In Swift:

collectionView.setContentOffset(CGPointZero, animated: true)

If you leave the view that houses the collection view, make a change in the 2nd view controller, and need the collection view to update upon returning:

@IBAction func unwindTo_CollectionViewVC(segue: UIStoryboardSegue) {
    //Automatic table reload upon unwind
    viewDidLoad()
    collectionView.reloadData()
    collectionView.setContentOffset(CGPointZero, animated: true)
}

In my situation the unwind is great because the viewDidLoad call will update the CoreData context, the reloadData call will make sure the collectionView updates to reflect the new CoreData context, and then the contentOffset will make sure the table sets back to the top.

Solution 5 - Iphone

If you view controller contains safe area, code:

collectionView.setContentOffset(CGPointZero, animated: true)

doesn't work, so you can use universal extension:

extension UIScrollView {
    func scrollToTop(_ animated: Bool) {
        var topContentOffset: CGPoint
        if #available(iOS 11.0, *) {
            topContentOffset = CGPoint(x: -safeAreaInsets.left, y: -safeAreaInsets.top)
        } else {
            topContentOffset = CGPoint(x: -contentInset.left, y: -contentInset.top)
        }
        setContentOffset(topContentOffset, animated: animated)
    }
}

Solution 6 - Iphone

CGPointZero in my case shifted the content of the collection view because you are not taking in count the content inset. This is what it worked for me:

    CGPoint topOffest = CGPointMake(0,-self.collectionView.contentInset.top);
    [self.collectionView setContentOffset:topOffest animated:YES];

Solution 7 - Iphone

Sorry I couldn't comment at the time of this writing, but I was using a UINavigationController and CGPointZero itself didn't get me to the very top so I had to use the following instead.

CGFloat compensateHeight = -(self.navigationController.navigationBar.bounds.size.height+[UIApplication sharedApplication].statusBarFrame.size.height);
[self.collectionView setContentOffset:CGPointMake(0, compensateHeight) animated:YES];

Hope this helps somebody in future. Cheers!

Solution 8 - Iphone

To deal with an UINavigationController and a transparent navigation bar, I had to calculate the extra top offset to perfectly match the position of the first element.

Swift 1.1 code:

     let topOffest = CGPointMake(0, -(self.collectionView?.contentInset.top ?? O))
     self.collectionView?.setContentOffset(topOffest, animated: true)

Cheers!

Solution 9 - Iphone

  • SWIFT 4.2 SOLUTION- Say I have a tableView with each tableViewCell containing a HorizontalCollectionView Due to reuse of cells, even though first tableViewCell is scrolled to say page 4, downwards, other cell is also set to page 4.

This works in such cases- In the cellForRowAt func in tableView, let cell = //declaring a cell using deque cell.myCollectionView.contentOffset = CGPoint(x:0,y:0)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMulletDevilView Question on Stackoverflow
Solution 1 - IphoneMick MacCallumView Answer on Stackoverflow
Solution 2 - IphoneNils HottView Answer on Stackoverflow
Solution 3 - IphoneDaniel GalaskoView Answer on Stackoverflow
Solution 4 - IphoneDave GView Answer on Stackoverflow
Solution 5 - IphoneAlexanderView Answer on Stackoverflow
Solution 6 - IphoneJavier Calatrava LlaveríaView Answer on Stackoverflow
Solution 7 - IphoneRyanView Answer on Stackoverflow
Solution 8 - IphoneKevin DelordView Answer on Stackoverflow
Solution 9 - IphonefinView Answer on Stackoverflow