[英]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.