Swift PlaygroundsでLazyVGridを学ぶ。

SwiftUI

概要:

iPadのアプリSwift Playgroundsの「グリッドを使った整理」のソースコードで、LazyVGridを中心に解説します。

LazyVGrid:SwiftUIの象徴的概念

まず、LazyVGridの理解を早めるため次の動画を見てください。

スマフォが縦の時に横4個ずつの四角が並んでいます。スマフォを横にすると、横4個は変わらず、四角のサイズを変更して配置しています。

これがまさにLazyVGridの役目です。

以下にContentView.swiftファイルのソースコード全文を載せてありますが、基本的に①②の2行だけでこの動作を実現しています。

import SwiftUI

struct ContentView: View {
    let columnLayout = Array(repeating: GridItem(), count: 4) // 
    @State private var selectedColor = Color.gray
    let allColors: [Color] = [
        .pink,
        .red,
        .orange,
        .yellow,
        .green,
        .mint,
        .teal,
        .cyan,
        .blue,
        .indigo,
        .purple,
        .brown,
        .gray
    ]
    var body: some View {
        VStack {
            Text("Selected Color")
                .font(.body)
                .fontWeight(.semibold)
                .foregroundColor(selectedColor)
                .padding(10)
            
            ScrollView {
                LazyVGrid(columns: columnLayout) {   // 
                   ForEach(allColors.indices, id: \.self) { index in
                       Button {
                            selectedColor = allColors[index]
                        } label: {
                            RoundedRectangle(cornerRadius: 4.0)
                                .aspectRatio(1.0, contentMode: ContentMode.fit)
                                .foregroundColor(allColors[index])
                        }
                        .buttonStyle(.plain)
                    }
                }
            }
        }
        .padding(10)
    }
}

2行です。すごいと思いませんか? 最初見た時感動しました!

LazyVGrid部分のソースコード解説

上のソースコードを画面全体構成とGridに関係するところだけにしたのが次です。

struct ContentView: View {
    let columnLayout = Array(repeating: GridItem(), count: 4) // 
    // 他の変数等の定義

    var body: some View {
        VStack {
            Text("Selected Color")
            ScrollView {
                LazyVGrid(columns: columnLayout) {   // 
                    // 各四角を描画する処理
                }
            }
        }
        .padding(10)
    }
}

①の行でLazyVGridのcolumnsプロパティに与える値を定義していますね。

columnsはGridItemという構造体の配列(つまり[GridItem])で渡すことになっていて、それがcolumnLayoutになります。

Array(repeating: GridItem(), count: 4) は以下と同等です。
[ GridItem(), GridItem(), GridItem(), GridItem() ]

つまり横方向には4つのItemが入りますと定義しているわけです。

これが最初の動画の横4つになっているわけですね。

count:の後の数字を他の数字、例えは7に変えると以下のようになります。

let columnLayout = Array(repeating: GridItem(), count: 7)

Gridの応用(LazyHGrid)

Apple DeveloperのLazyVGridページのサンプルプログラム内では以下のような使い方も紹介しています。さらに学びたい時の参考になります。

struct GridItemDemo: View {
    let rows = [
        GridItem(.fixed(30), spacing: 1),
        GridItem(.fixed(60), spacing: 10),
        GridItem(.fixed(90), spacing: 20),
        GridItem(.fixed(10), spacing: 50)
    ]

    var body: some View {
        ScrollView(.horizontal) {
            LazyHGrid(rows: rows, spacing: 5) {

LazyVGridが横方向に何個と決めたのに対し、LazyHGridは縦方向に何個を決めて表示します。

ここでは同じ4個のGridItemを縦方向に定義しているだけでなく、それぞれ固定のサイズやGrid間のスペースも設定しています。

ちなみに、
GridItemで定義するspacingはそのGridItem間のスペース、

GridItem(.fixed(60), spacing: 10)

LazyVGridやLazyHGridで設定するspacingはその列や行の間のスペース、

LazyHGrid(rows: rows, spacing: 5)

を意味します。設定しない場合のDefault値になります。

「グリッドを使った整理」のソースコードにもどり、試しに両方のspacingを0にすると以下のようになります。

struct ContentView: View {
    let columnLayout = Array(repeating: GridItem(.fixed(60), spacing: 0), count: 4) 
                // 省略
                LazyVGrid(columns: columnLayout, spacing: 0) {

なんか、簡単なゲームなら作れるような気がしてきたのは私だけでしょうか(笑)


アプリのタイトルが「グリッドを使った整理」ですので、まさしくGridに関する一連の動作が理解できるソースコードでした。

ソースコードはシンプルですので、色んな箇所を変更して見ると楽しいです。

最後まで読んで頂いて、ありがとうございます。

次回はForEachを中心にHashableプロトコルやid: \.selfなどをわかり易く解説して見たいと思います。

ご意見、ご指摘等ありましたら、コメントを頂けると大変嬉しいです。

コメント

タイトルとURLをコピーしました