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

问题描述

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

我走了这么远:

enter image description here

问题在于这种布局会不断重复,因此现在每6张图片中的一张显示得更大,而不是仅在第一组中出现。

这是我的布局代码

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,trailing: 2
  )

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

  pairItem.contentInsets = NSDirectionalEdgeInsets(
    top: 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。-3来自mainWithPairGroup中的3。而除以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,]
    )