1

I want to show images of different dimensions (800x600, 800x800, 800x1200 etc) in a collection view (each image is one cell). The width of the cell is static and equal to the width of the collection view, but the height needs to be dynamic, calculated based on the displayed image, so that we never crop any artwork!

I am using UICollectionViewCompositionalLayout and load cells from dedicated nibs like this:

collectionView.register(UINib(nibName: "Image", bundle: nil), forCellWithReuseIdentifier: "ImageCell")

and then

private func cell(collectionView: UICollectionView, indexPath: IndexPath, item: Item) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell...
    cell.setup(...)
    return cell
}

The ImageCell only has one image view constrained to its superview (the cell's contentView):

cell

The layout for this cell is using an .estimated height:

private func createImageSectionLayout() -> NSCollectionLayoutSection {
    let item = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(20)))
    let group = NSCollectionLayoutGroup.horizontal(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(20)), subitems: [item])
    let section = NSCollectionLayoutSection(group: group)
    section.interGroupSpacing = 16
    section.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 16, bottom: 16, trailing: 16)
    return section
}

Finally, I'm using ScaledHeightImageView, a UIImageView subclass that calculates the intrinsic size based on its image's aspect ratio (taken from here).

Now the problem is that when I setup the cell and calculate the intrinsic size, the imageView's width is the one from the storyboard, and not the one from the parent UICollectionView, so my cell's height is always wrong.

Can someone help me understand what is wrong with my setup?

I have tried to experiment with:

  • setting up the cell in func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath)
  • overriding layoutSubviews() in the UICollectionViewCell subclass
  • calling layoutIfNeeded() from several places

but nothing seems to work.

phi
  • 10,634
  • 6
  • 53
  • 88
  • Can you get your cells to auto-size their heights using a Flow layout? – DonMag Apr 19 '21 at 16:02
  • @DonMag this is part of a rather complex collection view which is already using compositional layout – phi Apr 19 '21 at 16:10
  • Sure... however, I'd suggest trying to get that `ScaledHeightImageView` cell to work in a basic flow layout first. If it's not working there, you may just be chasing the wrong thing trying to get it working in a compositional layout. – DonMag Apr 19 '21 at 16:26

0 Answers0