Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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

like image 703
Aman Gupta Avatar asked Aug 07 '18 04:08

Aman Gupta


People also ask

What is Uicollectionviewflowlayout?

A layout object that organizes items into a grid with optional header and footer views for each section.

How do I make a collection view dynamic height?

Make-CollectionView-Height-Dynamic-According-to-ContentAdd a height constraint to your collection view. Set its priority to 999. Set its constant to any value that only makes it reasonably visible on the storyboard. Change the bottom equal constraint of the collection view to greater or equal.

What is swift Uicollectionview?

An object that manages an ordered collection of data items and presents them using customizable layouts.


2 Answers

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:

like image 159
ale84 Avatar answered Sep 28 '22 19:09

ale84


Based on ale84's answer and because of the fact I needed that iOS 12 fix in multiple places I created a UICollectionViewCell extension which I named UICollectionViewCell+iOS12:

extension UICollectionViewCell {     /// This is a workaround method for self sizing collection view cells which stopped working for iOS 12     func setupSelfSizingForiOS12(contentView: UIView) {         contentView.translatesAutoresizingMaskIntoConstraints = false         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])     } } 

And then in your collection view cells we do something like this (if your cell is created in IB):

override func awakeFromNib() {     super.awakeFromNib()     if #available(iOS 12, *) { setupSelfSizingForiOS12(contentView: contentView) } } 
like image 27
Vasil Garov Avatar answered Sep 28 '22 20:09

Vasil Garov