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?

- 7,972
- 2
- 24
- 21

- 919
- 2
- 8
- 16
-
Can you show your code when having this problem? I am trying to get my scrollview to not scroll when I reload data lol i'm having the opposite of your problem! – Wayne Filkins Oct 12 '16 at 06:16
9 Answers
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];

- 129,200
- 40
- 280
- 281
-
-
1+1 `setContentOffset` helped me to work this for UIScrollView as well. – NeverHopeless Aug 28 '13 at 07:05
-
32In the event that you are using the `contentInsets`, you can use the following point for your content offset `CGPointMake(-collectionView.contentInset.left, -collectionView.contentInset.top)` – TPoschel Jan 06 '14 at 19:45
-
2The accepted answer (scrollToItemAtIndexPath) for me resets scroll to the first row, which places the header item (viewForSupplementaryElementOfKind) out of view. setContentOffset to CGPointZero places the scroll at the complete top, including any header cells. – Scott Heaberlin Feb 11 '14 at 05:08
-
2It also has the advantage that one doesen't need to verify if the index path exists (e.g.: empty collection view) – Adrian Jul 01 '15 at 12:31
You can use this method to scroll to any item you want:
- (void)scrollToItemAtIndexPath:(NSIndexPath *)indexPath
atScrollPosition:(UICollectionViewScrollPosition)scrollPosition
animated:(BOOL)animated
-
1
-
Forget it, comment below solves it. [collectionView setContentOffset:CGPointZero animated:YES]; – inigo333 Aug 20 '15 at 15:56
-
4A side note, but if you set animated:NO and wrap this in an animation block (such as UIView withSpring...) you can have a custom animation style/speed for the scrolling. – Dermot Aug 21 '15 at 06:06
-
Note that this implementation will also invoke scroll delegate methods, which is exactly what I wanted. Thanks. – ClockWise Jan 08 '19 at 12:03
-
1This solution is more suitable for scrolling to a specific item. "setContentOffset" is better & safer for simply scrolling to the top. This solution requires some check to avoid runtime exceptions. – Abdurrahman Mubeen Ali Jan 14 '19 at 15:49
-
**WARNING:** This can cause a crash on iOS 12 and earlier if content is still loading. I recommend using the method with setContentOffset instead. – Alain Stulz Mar 23 '20 at 11:08
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()

- 23,617
- 8
- 77
- 97
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.

- 12,042
- 7
- 57
- 83
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)
}
}

- 157
- 2
- 6
-
Code-only answers are discouraged. Please click on edit and add a paragraph or two summarising how your code addresses the question, or perhaps explain how your answer differs from the previous answers. Thanks – Nick Nov 28 '18 at 05:56
-
This is the only answer that takes into account safeAreaInsets. All the others answers scrolled to the incorrect position for my collectionView. – Steven Baughman Dec 09 '18 at 03:05
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];

- 9,493
- 4
- 53
- 47
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!

- 490
- 5
- 14
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!

- 2,498
- 24
- 22
- 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)

- 77
- 1
- 3