繁体   English   中英

"如何使用集合视图组合布局使集合视图内的单元格居中"

[英]How to center cells inside collection view using collection view compositional layout

我有以下工作任务:我需要实现电影院视图,其中有一个屏幕和一组座位,每行代表一个部分: 在此处输入图像描述<\/a>

数据来自代表座位的二维数组:

var seats = [[1, 2, 3, 4, 5],
             [1, 2, 3, 4, 5],
            [1, 2, 3, 4, 5, 6],
            [1, 2, 3, 4, 5, 6],
            [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
            [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
]

让每一行,或者至少每组具有相同数量项目的行,成为它自己的部分,并为布局提供一个部分提供者功能。 段提供者函数被赋予段号以及环境对象。 从该环境对象中,您可以了解集合视图的宽度。 现在只需给组或部分适当的插图。

为了说明,我能够实现这样的布局(三个部分,每部分的项目数是部分索引加一):

在此处输入图片说明

我不会让你悬念; 我只会向您展示该布局的代码。 它不漂亮; 我使用了一堆硬编码值。 这个想法只是生成布局以便向您展示一般原则。 但我相信您可以看到如何根据您自己的情况进行调整:

let config = UICollectionViewCompositionalLayoutConfiguration()
config.scrollDirection = .vertical
let inter = 5 as CGFloat
config.interSectionSpacing = 5
let layout = UICollectionViewCompositionalLayout(sectionProvider: { ix, environment in
    let side = 30 as CGFloat
    let cellsz = NSCollectionLayoutSize(widthDimension: .absolute(side), heightDimension: .fractionalHeight(1))
    let cell = NSCollectionLayoutItem(layoutSize: cellsz)
    let groupsz = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .absolute(side))
    let count = ix+1
    let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupsz, subitems: [cell])
    group.interItemSpacing = .fixed(inter)
    let sec = NSCollectionLayoutSection(group: group)
    let width = environment.container.contentSize.width
    let inset = (width - CGFloat(count)*side - (CGFloat(count)-1)*inter) / 2.0
    sec.contentInsets = .init(top: 0, leading: inset, bottom: 0, trailing: 0)
    return sec
}, configuration: config)

这可能不是唯一的方法。 我认为,您可以改为调用NSCollectionLayoutGroup.custom并手动布置单元格。 但我认为这不是一个糟糕的解决方案。

我还应该说,我不相信集合视图是获得您想要实现的结果的最佳方式。 直接在代码中自己布置座位视图可能会更好。

我在实现自己的键盘时遇到了同样的问题。 我的结果:键盘图像 这就是我在不使用常量的情况下做到的(Matt 很棒的答案的改进)。

  private func generateKeyboardLayout() -> UICollectionViewLayout {

    let groupInset = 3 / UIScreen.main.scale
    let layout = UICollectionViewCompositionalLayout { (sectionIndex, layoutEnvironment) -> NSCollectionLayoutSection? in
      let item = NSCollectionLayoutItem(
        layoutSize: NSCollectionLayoutSize(
          widthDimension: .fractionalWidth(1.0),
          heightDimension: .fractionalHeight(1.0)))
      
      let group = NSCollectionLayoutGroup.horizontal(
        layoutSize: NSCollectionLayoutSize(
          widthDimension: .fractionalWidth(1/10),
          heightDimension: .fractionalHeight(1/3)),
        subitems: [item])
      group.contentInsets = NSDirectionalEdgeInsets(top: groupInset, leading: groupInset, bottom: groupInset, trailing: groupInset)
      
      let count = Keyboard.getItems(at: keyboardSection).count
      let containerWidth = layoutEnvironment.container.contentSize.width
      let groupWidthDimension = group.layoutSize.widthDimension.dimension
      let itemWidth = containerWidth * groupWidthDimension
      let inset = (containerWidth - CGFloat(count) * itemWidth) / 2.0
  
      let section = NSCollectionLayoutSection(group: group)
      section.contentInsets = .init(top: 0, leading: round(inset), bottom: 0, trailing: 0)
      section.orthogonalScrollingBehavior = .continuous
      return section
    }
    return layout
  }

count表示每行的项目数

let count = Keyboard.getItems(at: keyboardSection).count

containerWidth是 CGFloat 中视图的确切宽度

let containerWidth = layoutEnvironment.container.contentSize.width

groupWidthDimension是每个组/键盘图块的宽度,包括应用的插图

let groupWidthDimension = group.layoutSize.widthDimension.dimension

itemWidth为您提供每个键盘图块的确切大小

let itemWidth = containerWidth * groupWidthDimension

插入(前导)根据containerWidth和所有项目的宽度之和的差计算,然后减半

let inset = (containerWidth - CGFloat(count) * itemWidth) / 2.0
section.contentInsets = .init(top: 0, leading: round(inset), bottom: 0, trailing: 0)

您可以使用NSCollectionLayoutGroup.custom(layoutSize:)<\/code>我们可以使用NSCollectionLayoutGroupCustomItemProvider<\/code>设置框架。

使用设置每个项目的框架

var customItems = [NSCollectionLayoutGroupCustomItem]()
            for item in 0..<itemCount {
                let frame = CGRect(x: yourCalculatedMargin, y: yPosition, width: layoutSize.widthDimension.dimension, height: layoutSize.heightDimension.dimension)
                customItems.append(NSCollectionLayoutGroupCustomItem(frame: frame))
            }
            return customItems

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM