Reputation: 1548
I'm trying to use custom UICollectionReusableView
(which has own class and XIB) in my UICollectionView
header. But after fetching data in the place of header I have nothing.
My steps:
Registering class in viewDidLoad:
[self.collectionView registerClass:[CollectionViewHeader class]
forSupplementaryViewOfKind: UICollectionElementKindSectionHeader
withReuseIdentifier:@"HeaderView"];
Trying to show:
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
UICollectionReusableView *reusableView = nil;
if (kind == UICollectionElementKindSectionHeader) {
CollectionViewHeader *collectionHeader = [self.collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"HeaderView" forIndexPath:indexPath];
NSInteger section = [indexPath section];
id <NSFetchedResultsSectionInfo> sectionInfo = [fetchRecipes sections][section];
collectionHeader.headerLabel.text = @"bla-bla-bla";
reusableView = collectionHeader;
}
return reusableView;
}
Can anybody tell me what's wrong? ) Thanks for any advice
Upvotes: 11
Views: 23592
Reputation: 760
class CustomFlowLayout: UICollectionViewFlowLayout {
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let attributesForElementsInRect = super.layoutAttributesForElements(in: rect)
var newAttributesForElementsInRect = [UICollectionViewLayoutAttributes]()
for attributes in attributesForElementsInRect! {
if !(attributes.representedElementKind == UICollectionElementKindSectionHeader
|| attributes.representedElementKind == UICollectionElementKindSectionFooter) {
// cells will be customise here, but Header and Footer will have layout without changes.
}
newAttributesForElementsInRect.append(attributes)
}
return newAttributesForElementsInRect
}
}
class YourViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let headerNib = UINib.init(nibName: "HeaderCell", bundle: nil)
collectionView.register(headerNib, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "HeaderCell")
let footerNib = UINib.init(nibName: "FooterCell", bundle: nil)
collectionView.register(footerNib, forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: "FooterCell")
}
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
switch kind {
case UICollectionElementKindSectionHeader:
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "HeaderCell", for: indexPath) as! HeaderCell
return headerView
case UICollectionElementKindSectionFooter:
let footerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "FooterCell", for: indexPath) as! FooterCell
return footerView
default:
return UICollectionReusableView()
}
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
return CGSize(width: collectionView.frame.width, height: 45)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
return CGSize(width: collectionView.frame.width, height: 25)
}
}
Upvotes: 1
Reputation: 4107
You was registering correctly the class and the delegate is implemented correctly.
The problem can be that the flow layout (by default) is not configured for header view, do you have this line in the code or interface file?
UICollectionViewFlowLayout *flowLayout = (UICollectionViewFlowLayout *)_collectionView.collectionViewLayout;
flowLayout.headerReferenceSize = CGSizeMake(CGRectGetWidth(_collectionView.bounds), 100);
Upvotes: 0
Reputation: 14329
Xcode 9, Swift 4:
Register UICollectionReusableView
in viewDidLoad
self.collectionView.register(UINib(nibName: "DashBoardCollectionReusableView", bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "ReuseIdentifier")
Upvotes: 1
Reputation: 11184
Actually there is can be few reasons:
(most common)
If u add u'r suplementaryView
in storyboard, and then try to register class
[self.stickyCollectionView registerClass:[<CLASSFORSUPPLEMENTARYVIEWW> class]
forSupplementaryViewOfKind:UICollectionElementKindSectionHeader
withReuseIdentifier:NSStringFromClass([<CLASSFORSUPPLEMENTARYVIEWW> class])];
u will get suplementaryView
, but not that u create (standard one) - u will see obj, but actually this is will be like placeholder.
Example:
Here u can see that obj was created, but outlets are nil (in this simple case only one outlet - _monthNameLabel
).
If u create separate Obj
for handling dataSourse/delegate for collectionView
and add reference outlet to it, and in init
methods try to register class to u'r outlet (assumed that view created in separate nib file), u will also receive same result like previous, but reason another - u'r outlet is nil here:
As solution u for example can use custom setter for this like:
#pragma mark - CustomAccessors
- (void)setcCollectionView:(UICollectionView *)collectionView
{
_collectionView = collectionView;
[self.stickyCollectionView registerNib:...];
}
u can use registerClass
instead of registerNib
Upvotes: 1
Reputation: 76
Just in case if someone needs solution. You don't have to register the header class using
[self.collectionView registerClass:...]
Just use the layout's delegate method to return the header class.
Upvotes: 1
Reputation: 3021
Register Your header nib/xib in the viewDidLoad section.
[self.collectionView registerNib: [UINib nibWithNibName:@"headerCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:@"headerCell"];
Create the custom supplementary view cell.
- (headerCollectionViewCell *)collectionView:(UICollectionView *)collectionViews viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
UICollectionReusableView *reusableView = nil;
if (kind == UICollectionElementKindSectionHeader) {
UINib *nib = [UINib nibWithNibName:@"headerCollectionViewCell" bundle:nil];
[collectionViews registerNib:nib forCellWithReuseIdentifier:@"headerCell"];
headerCollectionViewCell *collectionHeader = [collectionViews dequeueReusableCellWithReuseIdentifier:@"headerCell" forIndexPath:indexPath];
collectionHeader.titleLabel.text = @"What";
reusableView = collectionHeader;
}
return reusableView;
}
Upvotes: 10
Reputation: 42977
I think you are adding label to the xib. So you need to registerNib: for the header view instead of registerClass:
Upvotes: 14