2

I am experiencing problem with UICollectionViewFlowLayout.estimatedItemSize. The issue is that it does not work for iOS 9 & 10 but works fine for iOS 11. Here are the snapshots:

ScreenShot iOS-11 -> This is the expected behaviour.

ScreenShot iOS-10 -> There is nothing displayed here as the cell size is Zero. cellForItemAtIndex is never called.

ScreenShot iOS-9 -> Same as in iOS-10

According to https://developer.apple.com/videos/play/wwdc2014/226/, setting estimatedItemSize to a non-zero value, makes the autolayout to kick in and calls systemLayoutSizeFitting(targetSize:horizontalFittingPriority:verticalFittingPriority:) -> CGSize on UICollectionViewCell to compute size. So sizeForItemAt method need not be implemented.

Scroll Direction is Horizontal.

FYI - I am not using UICollectionViewFlowLayoutAutomaticSize and haven't tried it yet. I am not sure how it works and it got introduced only in iOS-10. But I need to support iOS-9. Also, according to wwdc2014/226 video, setting estimatedItemSize to non-zero value should be sufficient.

This is the code:

UICollectionViewCell:

class SingleTextCVC: UICollectionViewCell {

    @IBOutlet weak var textlabel: UILabel! {
        didSet {
            textlabel.textColor = UIColor.black
        }
    }

    override func awakeFromNib() {
        super.awakeFromNib()
        backgroundColor = UIColor.white
        layer.cornerRadius = 4
        clipsToBounds = true
    }
}

ViewController:

class CVHorzTextAutoDimenVC: UIViewController {

    @IBOutlet weak var collectionView: UICollectionView! {
        didSet {
            collectionView.delegate = self
            collectionView.dataSource = self
            collectionView.register(nib: SingleTextCVC.self)

            if let _layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {

                _layout.sectionInset = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)
                _layout.minimumInteritemSpacing = 16
                _layout.estimatedItemSize = CGSize(width: 100, height: 52)
            }
        }
    }

    fileprivate var textItems: [String] = [
        "Lorem",
        "Lorem ipsu",
        "Lorem ipsu dolor",
        "Lorem ipsum dolor sit",
        "Lorem ipsum dolor sit amet",
        "Lorem ipsum dolor sit amet, consectetur",
        "Lorem ipsum dolor sit amet, consectetur adipiscing ",
        "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
        "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer",
        "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer ne."
    ]

    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

extension CVHorzTextAutoDimenVC : UICollectionViewDataSource, UICollectionViewDelegate {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return textItems.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: SingleTextCVC.reuseIdentifier, for: indexPath) as! SingleTextCVC
        cell.textlabel.text = textItems[indexPath.row]
        return cell
    }
}

Please let me know what am I missing here?

Why does it work only for iOS-11?

Is it the expected behaviour. If yes, why?

If not, what's the solution?

user2601981
  • 137
  • 2
  • 8

2 Answers2

2
let layout = UICollectionViewFlowLayout() 
if #available(iOS 10.0, *) { 
layout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize
 } 
else { 
layout.estimatedItemSize = CGSize(width: 100, height: 52)
 }
tania_S
  • 1,262
  • 13
  • 23
0

Swift 5

let layout = UICollectionViewFlowLayout() 
layout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
yourCollectionView.collectionViewLayout = layout

Do not forget to design your cell so that its height can be determined through constraints.

Essam Mohamed Fahmi
  • 1,262
  • 16
  • 25