Embed CollectionView inside CollectionViewCell with dynamic height

446 Views Asked by At

Both collection views use compositional layout and diffable data source. Each outer collection view cell embeds a collectionView.

The outer collection view has estimated group height, i.e.

let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
        
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(300.0))
let group = NSCollectionLayoutGroup.vertical(layoutSize: groupSize, subitems: [item])
        
let section = NSCollectionLayoutSection(group: group)

Each cell's collection view is constraint to the lead, trail, top, bottom anchors of the cell's contentView. i.e.

NSLayoutConstraint.activate([
    cellView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
    cellView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
    cellView.topAnchor.constraint(equalTo: contentView.topAnchor),
    cellView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
])

Each cell's collection view can have a hight range from about 50 to 800.

The problem is how to size each cell to the actually content size of the cell's collection view. As the section layout does not allow provide cell's dimension individually.

If we give the cell hight estimation too low, like 50. Then the cell's collection view simply sized to 50 and vertically scrollable (which is undesired).

If we give the cell hight estimation too high, say 800. Then when the cell's collection view is small, there is a large white space left in the cell.

I can estimate an height using the cell's model at run-time. However, I'm struggled to find the place to invalidate the current layout then trigger an relayout using the new cell height.

1

There are 1 best solutions below

1
On

My problem is solved by this SO answer.

Collection View Compositional Layout with estimated height not working

The cell height can be updated, strangely, if as the above answer points out,

Setting both item and group with estimated height. And set the as horizontal layout.

In such case, the cell.

override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes

can get triggered correctly. So that I can update the cell layout attributes using the cell's collection view's content size.