Skip to content

Instantly share code, notes, and snippets.

@mikevoyt
Last active February 8, 2023 12:52
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save mikevoyt/4613982 to your computer and use it in GitHub Desktop.
Save mikevoyt/4613982 to your computer and use it in GitHub Desktop.
Example of how to create a pinned header with UICollectionView (i.e., a header that doesn't scroll with the rest of the cells). As simple as possible - assumes a single header, at index path [0,0], to be pinned at the top of the collection view.
//Override UICollectionViewFlowLayout class
@interface FixedHeaderLayout : UICollectionViewFlowLayout
@end
@implementation FixedHeaderLayout
//Override shouldInvalidateLayoutForBoundsChange to require a layout update when we scroll
- (BOOL) shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
return YES;
}
//Override layoutAttributesForElementsInRect to provide layout attributes with a fixed origin for the header
- (NSArray *) layoutAttributesForElementsInRect:(CGRect)rect {
NSMutableArray *result = [[super layoutAttributesForElementsInRect:rect] mutableCopy];
//see if there's already a header attributes object in the results; if so, remove it
NSArray *attrKinds = [result valueForKeyPath:@"representedElementKind"];
NSUInteger headerIndex = [attrKinds indexOfObject:UICollectionElementKindSectionHeader];
if (headerIndex != NSNotFound) {
[result removeObjectAtIndex:headerIndex];
}
CGPoint const contentOffset = self.collectionView.contentOffset;
CGSize headerSize = self.headerReferenceSize;
//create new layout attributes for header
UICollectionViewLayoutAttributes *newHeaderAttributes = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader withIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
CGRect frame = CGRectMake(0, contentOffset.y, headerSize.width, headerSize.height); //offset y by the amount scrolled
newHeaderAttributes.frame = frame;
newHeaderAttributes.zIndex = 1024;
[result addObject:newHeaderAttributes];
return result;
}
@end
@simplelife-patrick
Copy link

By using this sample, the header does be sticky as wished, thanks. But here is another issue involved: if some UIControl like button is also in header view, they can be interacted by touching correctly with this sample...

@fresh83
Copy link

fresh83 commented Jan 22, 2014

simplelife-patrick, is this true or did u figure out u were doing it wrong?

@Elenapocky
Copy link

Thank you for sharing this method =)

@ramunasjurgilas
Copy link

To work this code I needed to add headerReferenceSize like this:

self.headerReferenceSize = CGSizeMake(200, 60);

Otherwise for me it was not appearing header.

Thanks for the code! ;)

@harshvishu
Copy link

Didn't knew I had to put layoutAttributesForSupplementaryViewOfKind inside the call of layoutAttributesForElementsInRect:(CGRect)rect.

This has been a lot of help. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment