Reputation: 3803
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
...
Upvotes: 49
Views: 101623
Reputation: 81
None of above works if you forgot to enable accessory in your XIB file, don't forget to activate your desired section!
Upvotes: 5
Reputation: 2431
In swift like below
Register Header View
collectionView.register(HeaderView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, 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
Upvotes: 66
Reputation: 2643
If you don't set the header view in storyboard, you will have to register nib.
Example in viewDidLoad:
- (void)viewDidLoad
{
[self.collectionView registerClass:NSStringFromClass([YourOwnSubClass class]) forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"HeaderViewIdentifier"];
}
Anyway, you can also subclass UICollectionReusableView.
@interface YourOwnSubClass : UICollectionReusableView
then call delegate in your class example:
- (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;
}
And don't forget to set header size in collection view or in flow layout so header view will be visible.
Upvotes: 25