UICollectionViewCompositionalLayout :动态高度 UICollectionView 单元格,应该设置什么值才能具有良好的性能和正确的高度?

Che*_*eng 11 ios uicollectionview swift uicollectionviewcompositionallayout

我能够UICollectionView使用动态高度单元来实现,如下面的屏幕截图所示。单元格的高度将根据内容自动调整。

在此输入图像描述

这是实现这种结果的代码。

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
}
Run Code Online (Sandbox Code Playgroud)

我们注意到通过使用

heightDimension: .estimated(1)
Run Code Online (Sandbox Code Playgroud)

会产生较差的性能。等了2~3秒,页面标签切换成功。

如果我们将 更改heightDimension为更高的estimated值,则会显着提高性能。不到1秒,页面标签切换成功。

heightDimension: .estimated(400)
Run Code Online (Sandbox Code Playgroud)

然而,这会带来以下副作用。有些卡牌会随机产生如下所示的超调高度效果。

在此输入图像描述

在卡片中,我们为底部子视图设置了 1000 垂直内容拥抱优先级。但正如您在屏幕截图中看到的那样,底部视图仍然尝试自行增长以填充超出的高度。


我们现在的问题是

  1. 如果我们使用.estimated(1)高度,我们将获得正确的动态高度行为。但是,这会带来运行时性能不佳的代价。
  2. 如果我们提供足够大的值(例如.estimated(400)高度),我们将获得良好的运行时性能。然而,有些卡可以随机获得超调高度效果。

有谁知道正确的方法,可以UICollectionView在不影响运行时性能的情况下实现正确的动态单元高度?