Scroll UICollectionView to section header view
First, get the frame for the header in the section:
- (CGRect)frameForHeaderForSection:(NSInteger)section {
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:1 inSection:section];
UICollectionViewLayoutAttributes *attributes = [self.collectionView layoutAttributesForItemAtIndexPath:indexPath];
CGRect frameForFirstCell = attributes.frame;
CGFloat headerHeight = [self collectionView:_collectionView layout:_layout referenceSizeForHeaderInSection:section].height;
return CGRectOffset(frameForFirstCell, 0, -headerHeight);
}
Note: I just put a value of 1
for the indexPath.item
. You might need to change this to something appropriate for your implementation.
Then, scroll the UIScrollView
to the point at the top of the header:
- (void)scrollToTopOfSection:(NSInteger)section animated:(BOOL)animated {
CGRect headerRect = [self frameForHeaderForSection:section];
CGPoint topOfHeader = CGPointMake(0, headerRect.origin.y - _collectionView.contentInset.top);
[_collectionView setContentOffset:topOfHeader animated:animated];
}
Note: you must subtract the contentInset
, otherwise it will be discarded and your scrollview will scroll behind the status bar and/or navigation bar.
Seems like all the answers are overly complex. This works for me:
let attributes = self.collectionView.collectionViewLayout.layoutAttributesForSupplementaryViewOfKind(UICollectionElementKindSectionHeader, atIndexPath: NSIndexPath(forItem: 0, inSection: section))
self.collectionView.setContentOffset(CGPointMake(0, attributes!.frame.origin.y - self.collectionView.contentInset.top), animated: true)
Swift 3:
if let attributes = collectionView.collectionViewLayout.layoutAttributesForSupplementaryView(ofKind: UICollectionElementKindSectionHeader, at: IndexPath(item: 0, section: section)) {
collectionView.setContentOffset(CGPoint(x: 0, y: attributes.frame.origin.y - collectionView.contentInset.top), animated: true)
}
I think this may help you
UICollectionViewLayoutAttributes *attributes = [self.collectionView layoutAttributesForItemAtIndexPath:indexPath];
Then you can access the location through attributes.frame
Based on @pixelfreak
answer
Swift 4.2
+ iOS 11 Safe Area
SUPPORT (for iPhone X and above)
if let attributes = collectionView.layoutAttributesForSupplementaryElement(ofKind: UICollectionView.elementKindSectionHeader, at: IndexPath(item: 0, section: section)) {
var offsetY = attributes.frame.origin.y - collectionView.contentInset.top
if #available(iOS 11.0, *) {
offsetY -= collectionView.safeAreaInsets.top
}
collectionView.setContentOffset(CGPoint(x: 0, y: offsetY), animated: true) // or animated: false
}
HAPPY CODING