一、核心概念(白話解釋)
- Item(項):最小的顯示單元(比如一個商品卡片、一張圖片),定義單個元素的尺寸。
- Group(組):用來包裹 Item 的容器,決定 Item 在組內的排列方式(水平 / 垂直)和尺寸,一個組可以包含多個 Item。
- Section(分區):包裹 Group 的大容器,一個 UICollectionView 可以有多個 Section,每個 Section 可以用不同的佈局規則。
- Layout(佈局):最終把多個 Section 組合起來,形成完整的界面佈局。
二、代碼示例:快速實現一個基礎組合佈局
swift
import UIKit
class CompositionalLayoutDemoVC: UIViewController {
// 1. 創建集合視圖
private lazy var collectionView: UICollectionView = {
// 2. 配置組合佈局
let layout = createCompositionalLayout()
let cv = UICollectionView(frame: view.bounds, collectionViewLayout: layout)
cv.backgroundColor = .white
cv.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
cv.dataSource = self
return cv
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(collectionView)
}
// 3. 核心:創建組合佈局
private func createCompositionalLayout() -> UICollectionViewCompositionalLayout {
// Step 1: 定義Item(單個單元格)
// fractionalWidth(0.5):佔Group寬度的50% → 實現2列
// fractionalHeight(1.0):佔Group高度的100%
let itemSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(0.5),
heightDimension: .fractionalHeight(1.0)
)
let item = NSCollectionLayoutItem(layoutSize: itemSize)
// 給Item加間距(可選)
item.contentInsets = NSDirectionalEdgeInsets(top: 2, leading: 2, bottom: 2, trailing: 2)
// Step 2: 定義Group(包裹Item的容器)
// fractionalWidth(1.0):佔Section寬度的100%
// absolute(100):固定高度100pt
let groupSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1.0),
heightDimension: .absolute(100)
)
// .horizontal:Item在Group內水平排列
let group = NSCollectionLayoutGroup.horizontal(
layoutSize: groupSize,
subitems: [item]
)
// Step 3: 定義Section(包裹Group的分區)
let section = NSCollectionLayoutSection(group: group)
// 給Section加整體間距(可選)
section.contentInsets = NSDirectionalEdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10)
// Step 4: 創建最終佈局
return UICollectionViewCompositionalLayout(section: section)
}
}
// 4. 實現數據源(填充測試內容)
extension CompositionalLayoutDemoVC: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 20 // 測試用20個單元格
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
// 隨機背景色,方便看效果
cell.backgroundColor = UIColor(
red: CGFloat.random(in: 0...1),
green: CGFloat.random(in: 0...1),
blue: CGFloat.random(in: 0...1),
alpha: 1.0
)
return cell
}
}
三、關鍵知識點
1. 尺寸維度的 3 種定義方式
|
類型
|
用法
|
場景
|
|
|
|
按父容器比例適配(推薦,適配不同屏幕)
|
|
|
|
固定尺寸(如固定高度的卡片)
|
|
|
|
動態高度(如文字不確定的單元格,自動適配內容)
|
2. 常見佈局擴展(改幾行代碼就能實現)
- 瀑布流:給不同 Item 設置不同的
fractionalHeight或absolute高度即可; - 混合行列:一個 Group 裏放多個不同尺寸的 Item(比如 1 個寬 Item+2 個窄 Item);
- 垂直列表:把 Group 的排列方式改成
.vertical,Item 寬度設為1.0; - 多分區佈局:給不同 Section 設置不同的 Group/Item 規則(比如頂部 banner + 下方網格)。
3. 對比傳統流水佈局的優勢
- 無需自定義
UICollectionViewLayout子類,代碼量減少 80%; - 支持動態尺寸、複雜嵌套佈局,適配性更強;
- 內置對 UICollectionViewCompositionalLayoutConfiguration 的支持,可快速設置滾動方向、邊界效果等。
四、實際應用場景
- 電商 App:商品列表(網格 + 瀑布流混合)、首頁多模塊排版;
- 社交 App:朋友圈 / 動態流(文字 + 圖片 + 視頻混合佈局);
- 內容 App:資訊列表(標題 + 摘要 + 圖片的不同排版組合);
- 工具類 App:設置頁面、相冊網格 / 列表切換。