🗒️

【SwiftUI】LazyVGridの使用方法

2022/02/09に公開

はじめに

LazyVGridやLazyHGridを使用するとGridを作成することができます。
今回はLazyVGridの使用方法について紹介したいと思います。

環境

・ macOS: Monterey
・ Xcode: 13.2

公式ドキュメントを試す

まずは公式のドキュメントでコードが公開されているので試してみます。

var columns: [GridItem] = Array(repeating: .init(.flexible()), count: 2)
var body: some View {
    ScrollView {
        LazyVGrid(columns: columns) {
            ForEach((0...79), id: \.self) {
                let codepoint = $0 + 0x1f600
                let codepointString = String(format: "%02X", codepoint)
                Text("\(codepointString)")
                let emoji = String(Character(UnicodeScalar(codepoint)!))
                Text("\(emoji)")
            }
        }.font(.largeTitle)
    }
}

上記の画面にあるように絵文字のコード(テキスト)と絵文字が横並びに表示されます。
Array(repeating: .init(.flexible()), count: 2)ではrepeatingで指定した値をcountで指定した数の配列を作成します。
例えばこんな感じです。(※公式ドキュメントより)

let fiveZs = Array(repeating: "Z", count: 5)
print(fiveZs)
// Prints "["Z", "Z", "Z", "Z", "Z"]"

flexible()は本来minimumとmaximumを指定して使用しますが今回は指定していません。指定しない場合はflexible(minimum: CGFloat = 10, maximum: CGFloat = .infinity)がデフォルトで設定されます。
columnsを以下のように変更してみると良くわかります。

var columns: [GridItem] = Array(repeating: .init(.flexible(minimum: 10, maximum: 300)), count: 10)

※文字があると10列入らないので一旦Text("(codepointString)")を削除しましたので表示が絵文字だけになっています。またfontのサイズも.font(.system(size: 10))としています。

検証1

ここからは様々な使い方を検証してみます。

let data = Array(1...1000)
let layout = [GridItem(.adaptive(minimum: 30))]
var body: some View {
    ScrollView {
        LazyVGrid(columns: layout) {
            ForEach(data, id: \.self) { item in
            Text("\(item)")
            }
        }
    }
}

.adaptive(minimum: 30)では最小値のサイズとしています。
maximumも指定する事ができるが、指定しない場合はinfinity(デバイスの最大値幅)がデフォルトで設定されてます。
また上記のドキュメントのコードでは列数をcountで指定していたがadaptiveでは実装のサイズから自動で表示できる最大の列数で表示されます。minimumのサイズを変更してみると同時にRectangleを使用して幅を見てみると良くわかります。

let data = Array(1...1000)
let layout = [GridItem(.adaptive(minimum: 50))]
var body: some View {
    ScrollView {
        LazyVGrid(columns: layout) {
            ForEach(data, id: \.self) { item in
                VStack {
                    Text("\(item)")
                      Rectangle()
                        .frame(height: 5)
                }
            }
        }
    }
}

検証2

次はそれぞれの列のサイズを指定したり、列数や列同士の余白も調整できるように検証してみます。

let data = Array(1...100).map { "Index\($0)" }
let layout = [
    GridItem(.flexible(maximum: 80)),
    GridItem(.flexible(maximum: 100), spacing: 1),
    GridItem(.flexible(maximum: 150))
]
var body: some View {
    ScrollView {
        LazyVGrid(columns: layout, spacing: 0) {
            ForEach(data, id: \.self) { item in
                VStack {
                    Text("\(item)")
                      Rectangle()
                        .frame(height: 5)
                }
            }
        }
    }
}

GridItem(.flexible(maximum: CGFloat))の個数分配列され、maximumなど指定する事でそれぞれの列のサイズを指定する事ができます。またspacingを指定する事で余白を操作でき、GridItemに対して右側の余白に対して影響を及ぼすことも上記の画像より確認できます。

まとめ

Grid表示を使用する事で整ったViewやエクセルのような表もできるかと思います。(今後作ってみる)
次はLazyHGridについても色々試してみたいと思います。

Discussion