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

den*_*niz 1 dynamic ios uicollectionview swift uicollectionviewcompositionallayout

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

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

这是我们需要清除任何可能存在的歧义的象形图。 在此处输入图片说明

我只是在寻找:“是的,您可以通过组合布局来实现这一点,这就是如何......”。或者“不,你不能用组合来实现这个,你必须使用流布局或其他一些自定义布局。”

几个额外的要求:

  1. 提议的解决方案不应该推荐使用collectionView(_:layout:sizeForItemAt:)与流布局,因为这是我们试图避免的事情。如果这就是答案,那么您可以简单地说 - “不,这无法通过组合布局实现”。
  2. 提议的解决方案应该让集合视图根据单元格的内在内容大小确定如何适当地放置单元格。这类似于使用 tableview 的动态自调整大小功能UITableViewAutomaticDimension

背景资料:

  • 很清楚如何使用组合布局实现全宽但动态高度的单元格。看到这个交流
  • 此处此处记录具有自动内容大小的流布局的已知限制。那就是写了一本O'Reilly 书的人。基本上他说没有真正的自动调整流布局,即使苹果声称有。因此寻求尝试用组合布局解决这个问题。

JWK*_*JWK 8

您可以使用UICollectionViewCompositionalLayout. 就是这样:

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

重要的部分是组使用 占用可用宽度.fractionalWidth(1.0),但子项具有估计宽度。通过重写只要确保你的集合视图细胞可以自我大小sizeThatFits(_:)preferredLayoutAttributesFitting(_:)或使用自动布局。结果将是一个如下所示的布局:

在此处输入图片说明

要在同一个 中使用“第 1 部分”和“第 2 部分” UICollectionViewCompositionalLayout,只需使用创建您的布局init(sectionProvider:),您可以在其中返回适合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()
        }
    })
}
Run Code Online (Sandbox Code Playgroud)

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