HStack/VStackとLazyHStack/LazyVStack【SwiftUI】

SwiftUI

今回はHStack/VStackとLazyHStack/LazyVStack(ついでにScrollView)について説明していきます。

環境

  • Xcode12.5.1
  • iOS14.6
  • スクショはiPhone12Pro Maxで撮影

HStack/VStack

HStack はコンテンツを水平方向に並べていく、VStack は垂直方向に並べていくレイアウトになります。
まずは HStack でアイコンとテキストを水平方向に並べてみましょう。

struct ChildView: View {
    var body: some View {
        HStack {
            Image("icon")
                .resizable()
                .frame(width: 90.0, height: 90.0, alignment: .center)
                .clipShape(Circle())
            Text("I'm talking about SwiftUI.")
                .font(.system(size: 28.0))
        }
    }
}

iconを丸くしたりサイズを変えたりしていて少し見にくいですが、HStack のクロージャの中に書いたオブジェクトが水平に並んでいるのがわかります。

このTextの上に名前を表示してみましょう。

struct ChildView: View {
    var body: some View {
        HStack {
            Image("icon")
                .resizable()
                .frame(width: 90.0, height: 90.0, alignment: .center)
                .clipShape(Circle())
            VStack {
                Text("Shuhey-H")
                    .font(.system(size: 14.0))
                    .fontWeight(.thin)
                Text("I'm talking about SwiftUI.")
                    .font(.system(size: 28.0))
            }
        }
    }
}

VStack を使うことでTextの上に名前を表示できました。

ただ、中央寄せが気に入らないので、左寄せにしてみましょう。

struct ChildView: View {
    var body: some View {
        HStack {
            Image("icon")
                .resizable()
                .frame(width: 90.0, height: 90.0, alignment: .center)
                .clipShape(Circle())
            VStack(alignment: .leading) {
                Text("Shuhey-H")
                    .font(.system(size: 14.0))
                    .fontWeight(.thin)
                Text("I'm talking about SwiftUI.")
                    .font(.system(size: 28.0))
            }
        }
    }
}

VStack(alignment: .leading) とすることで、その中のオブジェクトは左寄せになります。 同じように .trailing を指定すると右寄せになります。何も指定しないor .centerを指定すると中央寄せになります。

ScrollView

さらにこのコンテンツを10個垂直に並べてみましょう。

struct ContentView: View {
    var body: some View {
        VStack {
            ForEach(0..<10) { i in
                ChildView()
            }
        }
    }
}

ただ VStack で並べただけなのでスクロールもできません。ScrolView に入れましょう。

struct ContentView: View {
    var body: some View {
        ScrollView {
            VStack {
                ForEach(0..<10) { i in
                    ChildView()
                }
            }
        }
    }
}

とても簡単にスクロールが実装できました。

LazyHStack/LazyVStack

では10個ではなく100個、1000個とたくさん並べていくとどうなるでしょう?

もちろん1000個でも表示することはできます。しかし、VStack は画面を表示する際に全てのコンテンツを生成し描画するという作りなので、数が多くなればなるほどメモリーへの負担が大きくなります。

VStackでただ1000個並べた場合は200MB近くメモリーを使用していますね。

ではこれを LazyVStack にするとどうでしょう。

同じ1000個でもメモリーの使用は42.5MBとかなり抑えることができています。

これは LazyHStack/LazyVStack は画面に表示される分だけを生成する仕組みになっているからです。画面に映らない余計なものは生成しないことで、メモリーの使用を抑えることができます。

もちろんLazyをつけてもつけなくても見た目に違いはありません。

たくさんのオブジェクトを並べるときは LazyHStack/LazyVStack を使用することをお勧めします。

コメント

  1. […] HStack/VStackとLazyHStack/LazyVStack【SwiftUI】 […]

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