title: UICollectionView and Supplementary View (header)
body: <p>Trying to add a a Supplementary view into my <code>UICollectionView</code> as a header. I'm having issues getting it to work.</p>
  
  <p>I use a custom <code>UICollectionViewFlowLayout</code> to return a <code>contentSize</code> that is always at least 1 pixel larger then the frame (I am using a <code>UIFreshControl</code> which will only work if the <code>UICollectionView</code> scrolls, and setting <code>collectionView.contentSize</code> directly does nothing) and to <code>invalidateLayout</code> on <code>sectionInsert</code> and <code>itemSize</code> changes:</p>
  
  <pre><code>-(void)setSectionInset:(UIEdgeInsets)sectionInset {
      if (UIEdgeInsetsEqualToEdgeInsets(super.sectionInset, sectionInset)) {
          return;
      }
  
      super.sectionInset = sectionInset;
  
      [self invalidateLayout];
  
  }
  
  -(void) setItemSize:(CGSize)itemSize {
      if (CGSizeEqualToSize(super.itemSize, itemSize)) {
          return;
      }
  
      super.itemSize = itemSize;
  
      [self invalidateLayout];
  }
  
  - (CGSize)collectionViewContentSize
  {
      CGFloat height = [super collectionViewContentSize].height;
  
      // Always returns a contentSize larger then frame so it can scroll and UIRefreshControl will work
      if (height &lt; self.collectionView.bounds.size.height) {
          height = self.collectionView.bounds.size.height + 1;
      }
  
      return CGSizeMake([super collectionViewContentSize].width, height);
  }
  </code></pre>
  
  <p>I created a <code>UICollectionReusableView</code> class which is just a <code>UIView</code> with a <code>UILabel</code>:</p>
  
  <pre><code>@implementation CollectionHeaderView
  
  - (id)initWithFrame:(CGRect)frame
  {
      self = [super initWithFrame:frame];
      if (self) {
          NSArray *arrayOfViews = [[NSBundle mainBundle] loadNibNamed:@"CollectionHeaderView" owner:self options:nil];
  
          if ([arrayOfViews count] &lt; 1) {
              return nil;
          }
  
          if (![[arrayOfViews objectAtIndex:0] isKindOfClass:[UICollectionViewCell class]]) {
              return nil;
          }
  
          self = [arrayOfViews objectAtIndex:0];
  
          self.headerLabel.text = @"This is a header. There are many like it.";
          self.backgroundColor = [UIColor yellowColor];
  
  
      }
      return self;
  }
  </code></pre>
  
  <p>Trying to implement it:</p>
  
  <pre><code>DatasetLayout *collectionViewFlowLayout = [[DatasetLayout alloc] init];
  collectionViewFlowLayout.itemSize = CGSizeMake(360, 160);
  collectionViewFlowLayout.scrollDirection = UICollectionViewScrollDirectionVertical;
  collectionViewFlowLayout.sectionInset = UIEdgeInsetsMake(16, 16, 16, 16);
  collectionViewFlowLayout.minimumInteritemSpacing = 16;
  collectionViewFlowLayout.minimumLineSpacing = 16;
  collectionViewFlowLayout.headerReferenceSize = CGSizeMake(0, 100);
  
  UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:collectionViewFlowLayout];
  collectionView.translatesAutoresizingMaskIntoConstraints = FALSE;
  collectionView.backgroundColor = [UIColor yellowColor];
  collectionView.delegate = self;
  collectionView.dataSource = self;
  </code></pre>
  
  <p>I register the class:</p>
  
  <pre><code>[self.collectionView registerClass:[CollectionHeaderView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CollectionHeaderView"];
  </code></pre>
  
  <p>and implement the delegate:</p>
  
  <pre><code>-(UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
  
      CollectionHeaderView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"CollectionHeaderView" forIndexPath:indexPath];
  
      headerView.headerLabel.text = @"Blarg!";
  
      return headerView;
  }
  </code></pre>
  
  <p>The line</p>
  
  <pre><code>collectionViewFlowLayout.headerReferenceSize = CGSizeMake(0, 100);
  </code></pre>
  
  <p>causes the error:</p>
  
  <pre><code>*** Assertion failure in -[UICollectionView _createPreparedSupplementaryViewForElementOfKind:atIndexPath:withLayoutAttributes:], /SourceCache/UIKit_Sim/UIKit-2380.17/UICollectionView.m:1150
  *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'UICollectionView dataSource is not set'
  </code></pre>
  
  <p>If I comment it out, it runs but no header.</p>
  
  <p>What am I doing wrong or not implementing?</p>