MENU

SwiftUI LazyVGridの使い方を徹底解説!グリッドレイアウトを簡単に実装

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()
        }
    }
}

このコードのポイントは以下の通りです:

  1. columns配列で列の定義を作成
  2. ScrollViewでスクロール可能にする
  3. LazyVGridに列定義とスペーシングを渡す
  4. 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もあります。

特徴LazyVGridLazyHGrid
スクロール方向縦(垂直)横(水平)
定義するもの列(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と組み合わせて使用
  • フォトギャラリーや商品一覧など、様々な用途に活用可能

参考リンク

プログラミングの独学におすすめ
プログラミング言語の人気オンラインコース
独学でプログラミングを学習している方で、エラーなどが発生して効率よく勉強ができないと悩む方は多いはず。Udemyは、プロの講師が動画で実際のプログラムを動かしながら教えてくれるオンライン講座です。講座の価格は、セール期間中には専門書籍を1冊買うよりも安く済むことが多いです。新しく学びたいプログラミング言語がある方は、ぜひUdemyでオンライン講座を探してみてください。
目次