UICollectionViewFlowLayout estimatedItemSize does not work properly with iOS12 though it works fine with iOS 11.*

Aman Gupta picture Aman Gupta · Aug 7, 2018 · Viewed 10.4k times · Source

For UICollectionView's dynamic height cells we use,

if let layout = self.collectionViewLayout as? UICollectionViewFlowLayout {
    layout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize
}

with the proper constraint of height and width, it works fine with iOS 11.* versions but it breaks and does not make the cells dynamic for iOS 12.0

Answer

ale84 picture ale84 · Sep 18, 2018

In my case, I solved this by explicitly adding the following constraints to the cell's contentView.

class Cell: UICollectionViewCell {
    // ...

    override func awakeFromNib() {
        super.awakeFromNib()

        // Addresses a separate issue and prevent auto layout warnings due to the temporary width constraint in the xib.
        contentView.translatesAutoresizingMaskIntoConstraints = false

        // Code below is needed to make the self-sizing cell work when building for iOS 12 from Xcode 10.0:
        let leftConstraint = contentView.leftAnchor.constraint(equalTo: leftAnchor)
        let rightConstraint = contentView.rightAnchor.constraint(equalTo: rightAnchor)
        let topConstraint = contentView.topAnchor.constraint(equalTo: topAnchor)
        let bottomConstraint = contentView.bottomAnchor.constraint(equalTo: bottomAnchor)
        NSLayoutConstraint.activate([leftConstraint, rightConstraint, topConstraint, bottomConstraint])
    }
}

These constraints are already in place inside the xib of the cell, but somehow they aren't enough for iOS 12.

The other threads that suggested calling collectionView.collectionViewLayout.invalidateLayout() in various places didn't help in my situation.

Sample code here: https://github.com/larrylegend/CollectionViewAutoSizingTest

This applies the workaround to code from a tutorial by https://medium.com/@wasinwiwongsak/uicollectionview-with-autosizing-cell-using-autolayout-in-ios-9-10-84ab5cdf35a2: