SwiftUIでグリッドレイアウトを実装したいとき、LazyVGrid
を使えば簡単に美しいレイアウトが作れます。この記事では、LazyVGridの基本から実践的な使い方まで、わかりやすく解説していきます。
LazyVGridとは?
LazyVGridは、SwiftUIで縦方向にスクロールするグリッドレイアウトを作成するためのコンポーネントです。
「Lazy」の意味
「Lazy(遅延)」という名前には重要な意味があります。LazyVGridは、画面に表示される要素だけをその都度生成するため、大量のデータを扱う場合でもパフォーマンスが優れています。
例えば、1000個のアイテムがあっても、画面に表示されている数個のアイテムだけがメモリに読み込まれます。スクロールすると、必要に応じて新しいアイテムが生成されるという仕組みです。
基本的な使い方
まずは、シンプルな3列のグリッドを作ってみましょう。
import SwiftUI
struct ContentView: View {
// 3つの列を定義
let columns = [
GridItem(.flexible()),
GridItem(.flexible()),
GridItem(.flexible())
]
var body: some View {
ScrollView {
LazyVGrid(columns: columns, spacing: 20) { // spacingで上下の余白を指定
ForEach(0..<20) { index in
Rectangle() // 背景色が青色の高さが100の四角形を描画
.fill(Color.blue)
.frame(height: 100)
.overlay( // 文字色が白色の数値を文字列として表示
Text("\(index)")
.foregroundColor(.white)
.font(.headline)
)
}
}
.padding()
}
}
}

このコードのポイントは以下の通りです:
columns
配列で列の定義を作成ScrollView
でスクロール可能にするLazyVGrid
に列定義とスペーシングを渡すForEach
でグリッドアイテムを生成
GridItemの3つのサイズタイプ
グリッドの列幅を制御するには、GridItem
の3つのサイズタイプを理解することが重要です。
1. .flexible()
– フレキシブルサイズ
利用可能なスペースを列の間で均等に分配します。
let columns = [
GridItem(.flexible()),
GridItem(.flexible())
]
最小・最大サイズも指定できます:
let columns = [
GridItem(.flexible(minimum: 50, maximum: 200)),
GridItem(.flexible(minimum: 50, maximum: 200))
]
2. .fixed()
– 固定サイズ
列の幅を固定値で指定します。
let columns = [
GridItem(.fixed(100)),
GridItem(.fixed(150)),
GridItem(.fixed(100))
]
3. .adaptive()
– 適応サイズ
指定した最小サイズに基づいて、画面幅に合わせて自動的に列数を調整します。レスポンシブデザインに最適です。
let columns = [
GridItem(.adaptive(minimum: 100))
]
この設定では:
- iPhoneの場合:3列程度
- iPadの場合:6列以上
というように、デバイスの画面幅に応じて自動調整されます。
実践例1:フォトギャラリー
実際のアプリでよく使われるフォトギャラリーを作ってみましょう。
struct PhotoGalleryView: View {
let columns = [
GridItem(.adaptive(minimum: 100))
]
let photos = Array(1...50)
var body: some View {
NavigationView {
ScrollView {
LazyVGrid(columns: columns, spacing: 10) {
ForEach(photos, id: \.self) { number in
Image(systemName: "photo.fill")
.resizable()
.scaledToFit()
.frame(height: 100)
.background(Color.blue.opacity(0.2))
.cornerRadius(12)
.shadow(radius: 3)
}
}
.padding()
}
.navigationTitle("フォトギャラリー")
}
}
}
実践例2:商品カタログ
ECアプリのような商品一覧画面も簡単に作れます。
struct Product: Identifiable {
let id = UUID()
let name: String
let price: Int
let color: Color
}
struct ProductGridView: View {
let columns = [
GridItem(.flexible()),
GridItem(.flexible())
]
let products = [
Product(name: "商品A", price: 1980, color: .red),
Product(name: "商品B", price: 2980, color: .blue),
Product(name: "商品C", price: 3980, color: .green),
Product(name: "商品D", price: 4980, color: .orange),
Product(name: "商品E", price: 5980, color: .purple),
Product(name: "商品F", price: 6980, color: .pink),
]
var body: some View {
ScrollView {
LazyVGrid(columns: columns, spacing: 16) {
ForEach(products) { product in
VStack(alignment: .leading, spacing: 8) {
RoundedRectangle(cornerRadius: 12)
.fill(product.color.opacity(0.3))
.frame(height: 150)
.overlay(
Image(systemName: "bag.fill")
.font(.system(size: 40))
.foregroundColor(product.color)
)
Text(product.name)
.font(.headline)
Text("¥\(product.price)")
.font(.subheadline)
.foregroundColor(.secondary)
}
.padding()
.background(Color.white)
.cornerRadius(16)
.shadow(radius: 5)
}
}
.padding()
}
.background(Color.gray.opacity(0.1))
}
}
LazyVGrid vs LazyHGrid
SwiftUIには、LazyVGridの兄弟としてLazyHGrid
もあります。
特徴 | LazyVGrid | LazyHGrid |
---|---|---|
スクロール方向 | 縦(垂直) | 横(水平) |
定義するもの | 列(columns) | 行(rows) |
使用例 | 写真ギャラリー、商品一覧 | カルーセル、カテゴリー選択 |
パフォーマンスのベストプラクティス
LazyVGridを使う際の注意点とコツをご紹介します。
1. identifiableプロトコルを使う
struct Item: Identifiable {
let id = UUID()
let name: String
}
// 推奨
ForEach(items) { item in
// ...
}
// 非推奨
ForEach(0..<items.count) { index in
// ...
}
2. 適切なスペーシングを設定
LazyVGrid(
columns: columns,
spacing: 16 // 行間のスペース
) {
// ...
}
// 列間のスペースはGridItemで設定
let columns = [
GridItem(.flexible(), spacing: 16),
GridItem(.flexible())
]
3. 画像の最適化
大量の画像を扱う場合は、適切なサイズにリサイズしておくことが重要です。
Image("photo")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 100, height: 100)
.clipped()
まとめ
LazyVGridは、SwiftUIでグリッドレイアウトを実装するための強力なツールです。主なポイントは以下の通りです。
- Lazy読み込みで大量データも快適に表示
.adaptive()
を使えば、レスポンシブデザインが簡単- ScrollViewと組み合わせて使用
- フォトギャラリーや商品一覧など、様々な用途に活用可能
参考リンク