I'm using AutoSizing cells with Autolayout and UICollectionView.
I can specify constraints in code on cell initialization:
func configureCell() {
snp.makeConstraints { (make) in
make.width.equalToSuperview()
}
}
However, the app crashes as the cell hasn't been yet added to the collectionView
.
Questions
At which stage of the cell
's lifecycle it is possible to add a
constraint with cell
's width
?
Is there any default way of making a cell
'swidth
equal to the
widthof the
collectionViewwithout accessing an instance of
UIScreenor
UIWindow`?
Edit The question is not duplicate, as it is not about how to use the AutoSizing cells feature, but at which stage of the cell lifecycle to apply constraints to achieve the desired result when working with AutoLayout.
The simple and easy solution lies in the underlying layout: Just call collectionViewContentSize on your myCollectionView. collectionViewLayout property and you get the height and width of the content as CGSize .
Use a cell registration to register cells with your collection view and configure each cell for display. You create a cell registration with your cell type and data item type as the registration's generic parameters, passing in a registration handler to configure the cell.
A layout object that organizes items into a grid with optional header and footer views for each section.
To implement self-sizing collection view cells you need to do two things:
estimatedItemSize
on UICollectionViewFlowLayout
preferredLayoutAttributesFitting(_:)
on your cellestimatedItemSize
on UICollectionViewFlowLayout
The default value of this property is CGSizeZero. Setting it to any other value causes the collection view to query each cell for its actual size using the cell’s preferredLayoutAttributesFitting(_:) method. If all of your cells are the same height, use the itemSize property, instead of this property, to specify the cell size instead.
This is just an estimate which is used to calculate the content size of the scroll view, set it to something sensible.
let collectionViewFlowLayout = UICollectionViewFlowLayout()
collectionViewFlowLayout.estimatedItemSize = CGSize(width: collectionView.frame.width, height: 100)
preferredLayoutAttributesFitting(_:)
on your UICollectionViewCell
subclassoverride func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
let autoLayoutAttributes = super.preferredLayoutAttributesFitting(layoutAttributes)
// Specify you want _full width_
let targetSize = CGSize(width: layoutAttributes.frame.width, height: 0)
// Calculate the size (height) using Auto Layout
let autoLayoutSize = contentView.systemLayoutSizeFitting(targetSize, withHorizontalFittingPriority: UILayoutPriority.required, verticalFittingPriority: UILayoutPriority.defaultLow)
let autoLayoutFrame = CGRect(origin: autoLayoutAttributes.frame.origin, size: autoLayoutSize)
// Assign the new size to the layout attributes
autoLayoutAttributes.frame = autoLayoutFrame
return autoLayoutAttributes
}
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