I have a UICollectionView
. I would like to add a header. My header would only be a UILabel
. I've :
1) selected "Section Header" as a Collection View accessory in the IB.
2) created a Collection Reusable View in the IB, on the side, declared as collectionViewHeader
.
3) added those lines :
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
if (kind == UICollectionElementKindSectionHeader) {
return collectionViewHeader;
}
return nil;
}
But they are never called.
Do I have to create a class just for that label in order to use
[self.collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"header"];
?
Why isn't it as simple as the UITableView
where you just drag and drop whatever header you want ?! Things are so complicated with UICollectionView
...
In swift like below
Register Header View
collectionView.registerClass(HeaderView.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "headerView")
In UICollectionViewDataSource
func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
let headerView = collectionView.dequeueReusableSupplementaryViewOfKind(UICollectionElementKindSectionHeader, withReuseIdentifier: "headerView", forIndexPath: indexPath)
headerView.frame.size.height = 100
return headerView
}
Important is that you are supply the flow layout with the header size
flowLayout.headerReferenceSize = CGSize(width: self.collectionView.frame.size.width, height: 100)
Otherwise the data source method will not get called
If you don't set the header in storyboard, you will have to register it.
In viewDidLoad:
- (void)viewDidLoad
{
[self.collectionView registerClass:[YourOwnSubClass class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"HeaderView"];
}
But any way, you will have to subclass UICollectionReusableView.
@interface YourOwnSubClass : UICollectionReusableView
then:
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView
viewForSupplementaryElementOfKind:(NSString *)kind
atIndexPath:(NSIndexPath *)indexPath
{
YourOwnSubClass *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:
UICollectionElementKindSectionHeader withReuseIdentifier:@"HeaderView" forIndexPath:indexPath];
[self updateSectionHeader:headerView forIndexPath:indexPath];
return headerView;
}
- (void)updateSectionHeader:(UICollectionReusableView *)header forIndexPath:(NSIndexPath *)indexPath
{
NSString *text = [NSString stringWithFormat:@"header #%i", indexPath.row];
header.label.text = text;
}
Simply add the view to UICollectionView
and change insets
collectionView.addSubview(headerView)
collectionView.contentInset.top = 300
headerView.frame = CGRect(x: 0,
y: -300,
width: collectionView.frame.size.width,
height: 300)