【SwiftUI】LazyHGrid & LazyVGrid(UICollectionView) の使い方【iOS14 & Xcode12】

以前こちらの記事で、SwiftUI での UICollectionViewQGrid)の使い方について解説しました。

今回は、iOS14 から導入された UICollectionVIew の SwiftUI 代替品である LazyHGridLazyVGrid について解説していきます。

【SwiftUI】LazyHGrid & LazyVGrid(UICollectionView) の使い方【iOS14 & Xcode12】

LazyHGrid行を横にLazyVGrid列を縦に並べます。

最初、「’H’Grid だから要素が横に並んで画面いっぱいで改行されるもの」とちょっと勘違いしていたのですが、

LazyHGrid は「要素が縦に一定数並んだ組みが横に並んでいく」という物で、

LazyVGrid はその逆で「要素が横に一定数並んだ組みが縦に並んでいく」物となります。

行と列って、よく「え〜とどっちが行だっけ?」と筆者はよくなるんですが、読者の皆さんはどうでしょうか。

とにかく、実際コードと実行結果をみて確認して行きましょう。

GridItem

LazyHGridLazyVGridGridItemを使って以下のように要素のサイズや行または列の要素数を定義します。

var rows: [GridItem] = Array(repeating: .init(.fixed(50)), count: 5)
var columns: [GridItem] = Array(repeating: .init(.fixed(100)), count: 3)

要素サイズは以下の3パターンで指定します。

  • fixed:固定サイズ
  • flexible:可変サイズ(最小・最大指定)
  • adaptive:可変サイズで、親View内ギリギリまで詰める

fixed は固定サイズの指定です。

flexible は 最小サイズと最大サイズを指定します。

adaptiveflexible とサイズ指定は同じですが、親Viewの範囲内ギリギリまで詰められます(fixed と flexible では GridItem の配列の要素数で行または列が繰り上げられる)。

注意点として、いずれも LazyHGrid の場合は高さが指定通りで幅はView要素に応じて広がり、LazyVGridの場合は幅が指定通りで高さがView要素に応じて広がるのが特徴です。

LazyHGrid

イニシャライザー

LazyHGrid(rows: [GridItem], alignment: VerticalAlignment, spacing: CGFloat?, pinnedViews: PinnedScrollableViews, content: () -> _)
  • rows:GridItem の配列を渡します。
  • alignment:行の配置を .center .top .bottom のいずれかで指定します。
  • spacing:行と行の間隔を指定します。
  • pinnedViews:View要素にセクションを設けた場合、ヘッダーとフッターを固定するかどうかを指定します。ヘッダーの場合は .sectionHeaders を、フッターの場合は .sectionFooters を指定します。

使用例

↓固定サイズの場合
var rows: [GridItem] = Array(repeating: .init(.fixed(50)), count: 5)
↓可変サイズの場合
var rows: [GridItem] = Array(repeating: .init(.flexible(minimum: 30, maximum: 50)), count: 5)

var body: some View {
    ScrollView(.horizontal) {
        LazyHGrid(rows: rows, alignment: .center, spacing: 8) {
            ForEach((1...100), id: \.self) { num in
                ZStack {
                    Rectangle().foregroundColor(.accentColor)
                    Text("\(num)").foregroundColor(.white)
                }
            }
        }
    }
}
LazyHGrid 実行結果

LazyVGrid

イニシャライザー

LazyHGrid とほぼ同じです。[GridItem] の引数ラベル名が columns になっているところと、alignmnent が HorizontalAlignment になっているだけです。

LazyVGrid(columns: [GridItem], alignment: HorizontalAlignment, spacing: CGFloat?, pinnedViews: PinnedScrollableViews, content: () -> _)

使用例

↓固定サイズの場合
var columns: [GridItem] = Array(repeating: .init(.fixed(50)), count: 5)
↓可変サイズの場合
var columns: [GridItem] = Array(repeating: .init(.flexible(minimum: 30, maximum: 50)), count: 5)

var body: some View {
    ScrollView(.vertical) {
        LazyVGrid(columns: columns, alignment: .center, spacing: 8) {
            ForEach((1...100), id: \.self) { num in
                ZStack {
                    Rectangle().foregroundColor(.accentColor)
                    Text("\(num)").foregroundColor(.white)
                }
            }
        }
    }
}
LazyVGrid 実行結果

以上