SwiftUI Grid 網格佈局教學
如果你想要製作像相簿、Instagram 個人頁面那樣的網格排版,LazyVGrid 和 LazyHGrid 是你的首選。
什麼是 LazyGrid?
"Lazy" (懶惰) 的意思跟 LazyHStack/LazyVStack 一樣,表示它只會建立即將顯示在螢幕上的 View。這對於包含大量圖片或資料的網格來說非常重要,能確保流暢的捲動體驗。
GridItem (網格項目設定)
在使用 Grid 之前,你需要先定義每一欄 (Column) 或每一列 (Row) 的佈局規則。這是透過 GridItem 來設定的。
GridItem 有三種尺寸模式:
- .fixed(size): 固定大小。
- .flexible(minimum, maximum): 彈性大小,會填滿剩餘空間 (最常用)。
- .adaptive(minimum, maximum): 自適應大小,盡可能放入越多項目越好。
LazyVGrid (垂直網格)
垂直網格需要定義「有幾欄 (Columns)」。
固定兩欄範例
let columns = [
GridItem(.flexible()), // 第一欄彈性
GridItem(.flexible()) // 第二欄彈性
]
ScrollView {
LazyVGrid(columns: columns, spacing: 20) {
ForEach(0..<20) { i in
Rectangle()
.fill(.orange)
.aspectRatio(1, contentMode: .fit) // 保持正方形 1:1
.overlay(Text("\(i)"))
}
}
.padding()
}
自適應欄位 (Adaptive)
這是最強大的模式,它會根據螢幕寬度自動決定要顯示幾欄。例如,在手機上顯示 3 欄,在 iPad 上可能顯示 6 欄。
// 設定最小寬度為 100,盡可能塞入越多欄位
let adaptiveColumn = [
GridItem(.adaptive(minimum: 100))
]
LazyVGrid(columns: adaptiveColumn) {
// ... items
}
LazyHGrid (水平網格)
水平網格則需要定義「有幾列 (Rows)」。
let rows = [
GridItem(.fixed(100)), // 第一列固定高度 100
GridItem(.fixed(100)) // 第二列固定高度 100
]
ScrollView(.horizontal) {
LazyHGrid(rows: rows) {
// ... items
}
}
Section (分區)
Grid 原生支援 Section 標頭 (Header) 和頁尾 (Footer),而且支援黏性標頭 (Sticky Header) 效果。
LazyVGrid(columns: columns, pinnedViews: [.sectionHeaders]) { // 開啟黏性標頭
Section(header: Text("第一區").font(.title).background(.white)) {
ForEach(0..<10) { i in
Text("Item \(i)")
}
}
Section(header: Text("第二區").font(.title).background(.white)) {
ForEach(10..<20) { i in
Text("Item \(i)")
}
}
}
透過 Grid,你可以輕鬆建立各種複雜且自適應的版面。