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