I am using a UICollectionView with a Flow Layout and trying to get the collectionView to size the cells appropriately according to AutoLayout constraints.
While the cells work as intended, I am running in to issues with the layout of any supplementary views that I add to the CollectionView.
Specifically, the supplementaryView will be in the wrong position (i.e., the y origin is incorrect) on initial layout, before 'correcting' itself after I scroll.
For reference, here is how I am configuring my cell sizing:
1. Set the collectionViewLayout's estimated item size
let collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.estimatedItemSize = CGSizeMake(375, 50.0)
layout.minimumInteritemSpacing = 0.0
layout.minimumLineSpacing = 0.0
let view = UICollectionView(frame: CGRectZero, collectionViewLayout: layout)
view.backgroundColor = UIColor.whiteColor()
view.alwaysBounceVertical = true
return view
}()
2. Use subclasses of AutoLayoutCollectionViewCell
class AutoLayoutCollectionViewCell: UICollectionViewCell {
override func preferredLayoutAttributesFittingAttributes(layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
layoutIfNeeded()
layoutAttributes.bounds.size.height = systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height
return layoutAttributes
}
}
Note that at this point, everything works as intended.
The next step is where we fail.
3. Provide a reference size for a header
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
return CGSizeMake(CGRectGetWidth(collectionView.frame), 30.0)
}
My question is: Why does this happen? How can I get this to correct? How am I supposed to handle supplementary views within a collectionView that self-sizes its cells??
I had the same problem, what solved it for me was to subclass UICollectionViewFlowLayout and override the following function:
override func invalidationContext(forPreferredLayoutAttributes preferredAttributes: UICollectionViewLayoutAttributes, withOriginalAttributes originalAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutInvalidationContext {
let context = super.invalidationContext(forPreferredLayoutAttributes: preferredAttributes, withOriginalAttributes: originalAttributes)
context.invalidateSupplementaryElements(ofKind: UICollectionElementKindSectionHeader,
at: [originalAttributes.indexPath])
return context
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With