簡體   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