UICollectionView Floating Headers on Top and Side

16.5k Views Asked by At

How do you implement headers in a UICollectionView? I know you can put in supplementary views, but I don't know how to make them "float" above a section like headers in a UITableView do.

Here's my situation: I have a collectionView with the cells laid out in a grid format. You can scroll horizontally and vertically. I want to have a header on top so that when you scroll horizontally it scrolls horizontally with it, but it doesn't scroll vertically. I also want the same sort of thing on the left side where it scrolls vertically with the collectionView but not horizontally. Is implementing this with supplementary views the right approach?

The final functionality I am looking for is similar to that of the Numbers spreadsheet app on iOS.

Thanks in advance for your help!

2

There are 2 best solutions below

2
On BEST ANSWER

Update for iOS9:

let flow = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
flow.sectionHeadersPinToVisibleBounds = true

Pass it along.

4
On

EDIT: As mentioned in the comments, this answer is valid, but not for multiple sections. See this blog for a better solution: http://blog.radi.ws/post/32905838158/sticky-headers-for-uicollectionview-using#notes


You need to specify that behaviour in your layout:

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
  NSMutableArray* attributesArray = [[super layoutAttributesForElementsInRect:rect] mutableCopy];

  BOOL headerVisible = NO;

  for (UICollectionViewLayoutAttributes *attributes in attributesArray) {
    if ([attributes.representedElementKind isEqualToString:UICollectionElementKindSectionHeader]) {
      headerVisible = YES;
      attributes.frame = CGRectMake(self.collectionView.contentOffset.x, 0, self.headerReferenceSize.width, self.headerReferenceSize.height);
      attributes.alpha = HEADER_ALPHA;
      attributes.zIndex = 2;
    }
  }

  if (!headerVisible) {
    UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader
                                                                                        atIndexPath:[NSIndexPath
                                                                                                     indexPathForItem:0
                                                                                                     inSection:0]];
    [attributesArray addObject:attributes];
  }

  return attributesArray;
}