UICollectionViewCompositionalLayout:自定义网格布局,其中只有一个单元格必须大于其余单元格

UICollectionViewCompositionalLayout: custom grid layout where only one cell has to be bigger than the rest

我正在尝试使用 UICollectionViewCompositionalLayout 构建照片网格,其中第三张图片显示较大,所有其他图片应该较小。

我已经走到这一步了:

问题是这种布局不断重复,所以现在每六张图片中就有一张显示得更大,而不是只出现在第一组中。

这是我的布局代码:

private func createLayout() -> UICollectionViewLayout {
  // Three photos next to eachother
  let tripletItem = NSCollectionLayoutItem(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1 / 3), heightDimension: .fractionalHeight(1)))
  tripletItem.contentInsets = .init(top: 2, leading: 2, bottom: 2, trailing: 2)

  let tripletGroup = NSCollectionLayoutGroup.horizontal(
    layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .fractionalWidth(1 / 3)),
    subitems: [tripletItem]
  )

  // Two small photos with a bigger photo next to it
  let mainItem = NSCollectionLayoutItem(
    layoutSize: NSCollectionLayoutSize(
      widthDimension: .fractionalWidth(2 / 3),
      heightDimension: .fractionalHeight(1)
    ))

  mainItem.contentInsets = NSDirectionalEdgeInsets(
    top: 2,
    leading: 2,
    bottom: 2,
    trailing: 2
  )

  let pairItem = NSCollectionLayoutItem(
    layoutSize: NSCollectionLayoutSize(
      widthDimension: .fractionalWidth(1),
      heightDimension: .fractionalHeight(0.5)
    ))

  pairItem.contentInsets = NSDirectionalEdgeInsets(
    top: 2,
    leading: 2,
    bottom: 2,
    trailing: 2
  )

  let pairGroup = NSCollectionLayoutGroup.vertical(
    layoutSize: NSCollectionLayoutSize(
      widthDimension: .fractionalWidth(1 / 3),
      heightDimension: .fractionalHeight(1)
    ),
    subitem: pairItem,
    count: 2
  )

  let mainWithPairGroup = NSCollectionLayoutGroup.horizontal(
    layoutSize: NSCollectionLayoutSize(
      widthDimension: .fractionalWidth(1),
      heightDimension: .fractionalWidth(2 / 3)
    ),
    subitems: [pairGroup, mainItem]
  )

  let nestedGroup = NSCollectionLayoutGroup.vertical(
    layoutSize: NSCollectionLayoutSize(
      widthDimension: .fractionalWidth(1),
      heightDimension: .fractionalWidth(1)
    ),
    subitems: [
      mainWithPairGroup,
      tripletGroup,
    ]
  )

  let section = NSCollectionLayoutSection(group: nestedGroup)
  let layout = UICollectionViewCompositionalLayout(section: section)
  return layout
}

如何使第一组 (mainWithPairGroup) 只使用一次,然后 tripletGroup 一遍又一遍地重复?

您的部分有两个子项目:mainWithPairGroup 和 tripletGroup。当您的项目多于这两个子组的空间时,该组将一遍又一遍地重复。如果您想改为使用 mainWithPairGroup 然后使用无限制的 tripletGroup,您可以有两个部分并更改您的组合布局以使用部分提供程序而不是单个部分。然后在您的第一部分中您将只使用 mainWithPairGroup,而在您的第二部分中您可以只使用 tripletGroup。这样做的问题是您现在必须更改数据源方法以允许容纳这两个部分。

如果您知道在创建布局时拥有的项目数,那么您可以创建一组计数等于 (numberOfItems - 3) / 3 的 tripletGroups。-3 来自 3 in mainWithPairGroup 和除以 3 来自每个 tripletGroup 中的项目数。然后在您的 nestedGroup 中,您的子项将是 mainWithPairGroup 和您的 tripletGroups 组。

    let groupedTripletGroup = NSCollectionLayoutGroup.vertical(
      layoutSize: .init(
        .fractionalWidth(1),
        .fractionalHeight(1)),
      subitem: tripletGroup, 
      count: (numberOfItems - 3)/3)

    let nestedGroup = NSCollectionLayoutGroup.vertical(
      layoutSize: NSCollectionLayoutSize(
        widthDimension: .fractionalWidth(1),
        heightDimension: .fractionalWidth(1)),
      subitems: [
        mainWithPairGroup,
        groupedTripletGroup,
      ]
    )