Created
July 4, 2014 05:51
-
-
Save timheuer/98bed7855f45780338e8 to your computer and use it in GitHub Desktop.
FlowLayoutWithStickyHeaders
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // FlowLayoutWithStickyHeaders.h | |
| // From: http://blog.radi.ws/post/32905838158/sticky-headers-for-uicollectionview-using | |
| // | |
| // Created by Tim Heuer on 7/3/14. | |
| // | |
| #import <UIKit/UIKit.h> | |
| @interface FlowLayoutWithStickyHeaders : UICollectionViewFlowLayout | |
| @end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // FlowLayoutWithStickyHeaders.m | |
| // From: http://blog.radi.ws/post/32905838158/sticky-headers-for-uicollectionview-using | |
| // | |
| // Created by Tim Heuer on 7/3/14. | |
| // | |
| #import "FlowLayoutWithStickyHeaders.h" | |
| @implementation FlowLayoutWithStickyHeaders | |
| - (NSArray *) layoutAttributesForElementsInRect:(CGRect)rect { | |
| NSMutableArray *answer = [[super layoutAttributesForElementsInRect:rect] mutableCopy]; | |
| UICollectionView * const cv = self.collectionView; | |
| CGPoint const contentOffset = cv.contentOffset; | |
| NSMutableIndexSet *missingSections = [NSMutableIndexSet indexSet]; | |
| for (UICollectionViewLayoutAttributes *layoutAttributes in answer) { | |
| if (layoutAttributes.representedElementCategory == UICollectionElementCategoryCell) { | |
| [missingSections addIndex:layoutAttributes.indexPath.section]; | |
| } | |
| } | |
| for (UICollectionViewLayoutAttributes *layoutAttributes in answer) { | |
| if ([layoutAttributes.representedElementKind isEqualToString:UICollectionElementKindSectionHeader]) { | |
| [missingSections removeIndex:layoutAttributes.indexPath.section]; | |
| } | |
| } | |
| [missingSections enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) { | |
| NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:idx]; | |
| UICollectionViewLayoutAttributes *layoutAttributes = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:indexPath]; | |
| [answer addObject:layoutAttributes]; | |
| }]; | |
| for (UICollectionViewLayoutAttributes *layoutAttributes in answer) { | |
| if ([layoutAttributes.representedElementKind isEqualToString:UICollectionElementKindSectionHeader]) { | |
| NSInteger section = layoutAttributes.indexPath.section; | |
| NSInteger numberOfItemsInSection = [cv numberOfItemsInSection:section]; | |
| NSIndexPath *firstCellIndexPath = [NSIndexPath indexPathForItem:0 inSection:section]; | |
| NSIndexPath *lastCellIndexPath = [NSIndexPath indexPathForItem:MAX(0, (numberOfItemsInSection - 1)) inSection:section]; | |
| UICollectionViewLayoutAttributes *firstCellAttrs = [self layoutAttributesForItemAtIndexPath:firstCellIndexPath]; | |
| UICollectionViewLayoutAttributes *lastCellAttrs = [self layoutAttributesForItemAtIndexPath:lastCellIndexPath]; | |
| CGFloat headerHeight = CGRectGetHeight(layoutAttributes.frame); | |
| CGPoint origin = layoutAttributes.frame.origin; | |
| origin.y = MIN( | |
| MAX( | |
| contentOffset.y, | |
| (CGRectGetMinY(firstCellAttrs.frame) - headerHeight) | |
| ), | |
| (CGRectGetMaxY(lastCellAttrs.frame) - headerHeight) | |
| ); | |
| layoutAttributes.zIndex = 1024; | |
| 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