Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save nonamelive/5601389 to your computer and use it in GitHub Desktop.
Save nonamelive/5601389 to your computer and use it in GitHub Desktop.
A collection view flow layout with floating headers support, compatible with PSTCollectionView. Thanks to @cocotutch! The original answer on StackOverflow can be found at http://stackoverflow.com/questions/13511733/how-to-make-supplementary-view-float-in-uicollectionview-as-section-headers-do-i/13678922#13678922
#import "PSTCollectionView.h"
@implementation CollectionViewFloatingHeaderFlowLayout
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSMutableArray *answer = [[super layoutAttributesForElementsInRect:rect] mutableCopy];
PSTCollectionView *const cv = self.collectionView;
CGPoint const contentOffset = cv.contentOffset;
NSMutableIndexSet *missingSections = [NSMutableIndexSet indexSet];
for (PSTCollectionViewLayoutAttributes *layoutAttributes in answer)
{
if (layoutAttributes.representedElementCategory == PSTCollectionElementCategoryCell)
{
[missingSections addIndex:layoutAttributes.indexPath.section];
}
layoutAttributes.zIndex = -1;
}
for (PSTCollectionViewLayoutAttributes *layoutAttributes in answer)
{
if ([layoutAttributes.representedElementKind isEqualToString:PSTCollectionElementKindSectionHeader])
{
[missingSections removeIndex:layoutAttributes.indexPath.section];
}
}
[missingSections enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:idx];
PSTCollectionViewLayoutAttributes *layoutAttributes = [self layoutAttributesForSupplementaryViewOfKind:PSTCollectionElementKindSectionHeader atIndexPath:indexPath];
[answer addObject:layoutAttributes];
}];
for (PSTCollectionViewLayoutAttributes *layoutAttributes in answer)
{
if ([layoutAttributes.representedElementKind isEqualToString:PSTCollectionElementKindSectionHeader])
{
NSInteger section = layoutAttributes.indexPath.section;
NSInteger numberOfItemsInSection = [cv numberOfItemsInSection:section];
NSIndexPath *firstObjectIndexPath = [NSIndexPath indexPathForItem:0 inSection:section];
NSIndexPath *lastObjectIndexPath = [NSIndexPath indexPathForItem:MAX(0, (numberOfItemsInSection - 1)) inSection:section];
PSTCollectionViewLayoutAttributes *firstObjectAttrs;
PSTCollectionViewLayoutAttributes *lastObjectAttrs;
if (numberOfItemsInSection > 0)
{
firstObjectAttrs = [self layoutAttributesForItemAtIndexPath:firstObjectIndexPath];
lastObjectAttrs = [self layoutAttributesForItemAtIndexPath:lastObjectIndexPath];
}
else
{
firstObjectAttrs = [self layoutAttributesForSupplementaryViewOfKind:PSTCollectionElementKindSectionHeader
atIndexPath:firstObjectIndexPath];
lastObjectAttrs = [self layoutAttributesForSupplementaryViewOfKind:PSTCollectionElementKindSectionFooter
atIndexPath:lastObjectIndexPath];
}
CGFloat headerHeight = CGRectGetHeight(layoutAttributes.frame);
CGPoint origin = layoutAttributes.frame.origin;
origin.y = MIN(
MAX(
contentOffset.y + cv.contentInset.top,
(CGRectGetMinY(firstObjectAttrs.frame) - headerHeight)
),
(CGRectGetMaxY(lastObjectAttrs.frame) - headerHeight)
);
layoutAttributes.zIndex = 0;
layoutAttributes.frame = (CGRect) {
.origin = origin,
.size = layoutAttributes.frame.size
};
}
}
return answer;
}
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBound
{
return YES;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment