是否可以使用组合布局创建具有动态宽度但固定高度的单元格

Is it possible to create cells with dynamic width but fixed height using Compositional Layout

TLDR; 根据部分,我需要调整单元格的大小:

  1. 固定宽度但动态高度(例如,全屏宽度和自动高度取决于内容)
  2. 动态宽度但固定高度(第一个单元格可以是 120pt 宽,第二个单元格可以是 155pt 宽,等等)

这是我们需要清除可能存在的任何歧义的象形图。

我正在寻找:"Yes, you can achieve this with compositional layout and here is how..."。或者 "No, you cannot implement this with compositional, you must use flow layout or some other custom layout."

几个额外的要求:

  1. 建议的解决方案不应推荐使用 collectionView(_:layout:sizeForItemAt:) 流式布局,因为这是我们试图避免的事情。如果这是答案,那么您可以简单地说 - "No, this cannot be achieved with compositional layouts".
  2. 提议的解决方案应该让集合视图根据其固有内容大小确定如何适当地放置单元格。这类似于 UITableViewAutomaticDimension
  3. 使用 tableview 的动态自调整大小功能

背景资料:

您可以使用 UICollectionViewCompositionalLayout 构建 "section 2" 布局。方法如下:

let layoutSize = NSCollectionLayoutSize(
    widthDimension: .estimated(100),
    heightDimension: .absolute(32)
)

let group = NSCollectionLayoutGroup.horizontal(
    layoutSize: .init(
        widthDimension: .fractionalWidth(1.0),
        heightDimension: layoutSize.heightDimension
    ),
    subitems: [.init(layoutSize: layoutSize)]
)
group.interItemSpacing = .fixed(8)

let section = NSCollectionLayoutSection(group: group)
section.contentInsets = .init(top: 0, leading: 16, bottom: 0, trailing: 16)
section.interGroupSpacing = 8

return .init(section: section)

重要的部分是组使用 .fractionalWidth(1.0) 占用可用宽度,但子项具有估计宽度。只需确保您的集合视图单元格可以通过覆盖 sizeThatFits(_:)preferredLayoutAttributesFitting(_:) 或使用自动布局来自行调整大小。结果将是如下所示的布局:

要在同一个 UICollectionViewCompositionalLayout 中使用 "section 1" 和 "section 2",只需使用 init(sectionProvider:) 创建您的布局,其中您 return 适当的 NSCollectionLayoutSection 当前节标识符:

func createCollectionViewLayout() -> UICollectionViewCompositionalLayout {
    .init(sectionProvider: { [weak self] sectionIndex, _ in
        guard let sectionIdentifier = self?.dataSource.snapshot().sectionIdentifiers[sectionIndex] else { return nil }
        switch sectionIdentifier {
        case .section1: return self?.createSection1()
        case .section2: return self?.createSection2()
        }
    })
}

值得注意的是,如果您的视图控制器在 iOS 13+ 上使用默认 pageSheet 样式呈现,您可能会看到此布局的一些奇怪行为。我在这里有一个 related question(使用稍微不同的布局)。