I am able to achieve UICollectionView
with dynamic height cell, as shown in the following screenshot. Height of the cell will be automatically adjusted based on content.
Here's is the code to achieve such outcome.
private func updateListLayout() {
// Item
let itemSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1.0),
heightDimension: .estimated(1)
)
let item = NSCollectionLayoutItem(layoutSize: itemSize)
item.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)
// Group
let groupSize = itemSize
//let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitem: item, count: 1)
group.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0)
group.interItemSpacing = .fixed(0)
let section = NSCollectionLayoutSection(group: group)
// Spacing for collection view's leading & trailing & bottom. For top, it is the spacing between header and item
section.contentInsets = NSDirectionalEdgeInsets(
top: DashboardViewController.padding * 2,
leading: DashboardViewController.padding,
bottom: DashboardViewController.padding * 2,
trailing: DashboardViewController.padding
)
// Vertical spacing between cards within different group.
section.interGroupSpacing = DashboardViewController.padding
let headerFooterSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1.0),
heightDimension: .estimated(1)
)
let sectionHeader = NSCollectionLayoutBoundarySupplementaryItem(
layoutSize: headerFooterSize,
elementKind: UICollectionView.elementKindSectionHeader,
alignment: .top
)
section.boundarySupplementaryItems = [sectionHeader]
let compositionalLayout = UICollectionViewCompositionalLayout(section: section)
// Switch the layout to UICollectionViewCompositionalLayout
collectionView.collectionViewLayout = compositionalLayout
}
We notice that by using
heightDimension: .estimated(1)
will yield poor performance. It took 2 to 3 seconds, to switch the page tab successfully.
If we change the heightDimension
to a higher estimated
value, that will increase the performance significantly. It took less than 1 second, to switch the page tab successfully.
heightDimension: .estimated(400)
However, that comes with the following side-effect. Some cards will randomly have an overshot height effect as shown below.
Within a card, we have value 1000 Vertical Content Hugging Priority for the bottom subview. But as you can see in the screenshot, bottom view still try to grow itself to fill up the overshot height.
Our problem right now is
- If we are using
.estimated(1)
for height, we will get correct dynamic height behavior. But, that comes with cost of poor runtime performance. - If we provide a large enough value like
.estimated(400)
for height, we will get a good runtime performance. However, some card can randomly get an overshoot height effect.
Do anyone know the right way, to achieve UICollectionView
with correct dynamic cell height, without impacting runtime performance?