SwiftUIのLazyVGridは子ビューに指定したViewをグリッド状に並べることができるViewです。
ただし遅延して表示するため、レイアウトを組む場合Viewのスペースを割り当てる優先順位を考慮する必要があります。
どう考慮すべきかをHStack
の子ビューにLazyVGrid
を指定する場合で解説します。
バージョン | |
---|---|
Xcode | 15.1 |
iOS | 17.0 |
macOS | Sonoma 14.0 |
作成物
HStack
の子ビューにLazyVGrid
(グリッド状に並べた絵文字)とButton
を指定し、このようなViewを作成します。
Viewのスペースを割り当てる優先順位を考慮しない場合
Viewのスペースを割り当てる優先順位を考慮せず、以下のように実装しビルドするとViewが中央に寄ってしまいます。
LazyVGridSample.swift
struct LazyVGridSample: View {
var body: some View {
HStack {
LazyVGrid(columns: [GridItem(.adaptive(minimum: 20))]) {
ForEach((0...24), id: \.self) {
let codepoint = $0 + 0x1f600
let emoji = String(Character(UnicodeScalar(codepoint)!))
Text("\(emoji)")
}
}
Button(
action: { },
label: { Text("ボタン") }
)
.frame(width: 60)
}
.padding(16)
}
}
LazyVGrid
は遅延して表示されるため、Button
が先に表示されることが原因となります。
Viewのスペースを割り当てる優先順位を考慮する場合
上記の問題を解決するために、layoutPriorityを用いてViewのスペースを割り当てる優先順位を変更します。
LazyVGrid
に.layoutPriority(1)
を指定し、Button
に.layoutPriority(0)
を指定します。
LazyVGridSample.swift
struct LazyVGridSample: View {
var body: some View {
HStack {
LazyVGrid(columns: [GridItem(.adaptive(minimum: 20))]) {
ForEach((0...24), id: \.self) {
let codepoint = $0 + 0x1f600
let emoji = String(Character(UnicodeScalar(codepoint)!))
Text("\(emoji)")
}
}
.layoutPriority(1)
Button(
action: { },
label: { Text("ボタン") }
)
.frame(width: 60)
.layoutPriority(0)
}
.padding(16)
}
}
するとLazyVGrid
を表示するスペースの優先順位が高くなるため、このように表示できます。