dasukoの技術ブログ

現役エンジニアのブログです。

【SwiftUI】VStack、HStack、ZStackについて

概要

SwiftUIでは複数のViewの配置を定義するためにHStackVStackZStackといったStackViewを使います。

StackViewを使用した場合、デフォルトでコンテンツを中央揃えにし、かつわずかな程よい間隔を挿入してくれます。

HStack

子Viewを水平に配置します。

サンプル

item1item5という5つのテキストを水平に配置したい場合は以下のようになります。

import SwiftUI

struct ContentView: View {
    var body: some View {
        HStack(
            alignment: .top,
            spacing: 10
        ) {
            ForEach(
                1...5,
                id: \.self
            ) {
                Text("Item \($0)")
            }
        }
    }
}

プレビューはこんな感じです。

f:id:dasuko:20210216231757p:plain

 

ちなみにspacing0にするとこんな感じでテキストの間隔がなくなります。

f:id:dasuko:20210216232011p:plain

VStack

子Viewを垂直に配置します。

サンプル

item1item5という5つのテキストを垂直に配置したい場合は以下のようになります。

struct ContentView: View {
    var body: some View {
        VStack(
            alignment: .leading,
            spacing: 10
        ) {
            ForEach(
                1...5,
                id: \.self
            ) {
                Text("Item \($0)")
            }
        }
    }
}

プレビューはこんな感じです。

f:id:dasuko:20210216232445p:plain

ちなみにspacing50にするとこんな感じでテキストの感覚が大きくなります。

f:id:dasuko:20210216232400p:plain

ZStack

子Viewをオーバーレイします。

Stackは子Viewを宣言順にZ方向に重ねます。

後から宣言したViewは前のViewよりも上に表示されます。

サンプル

item1item5というテキストを重ねて表示する場合は以下のようになります。

import SwiftUI

struct ContentView: View {
    var body: some View {
        ZStack {
            ForEach(
                1...5,
                id: \.self
            ) {
                Text("Item \($0)")
            }
        }
    }
}

プレビューはこんな感じです。

上に重なってますね。

f:id:dasuko:20210216233354p:plain

テキストだとわかりづらいので、Appleのドキュメントにあるサンプルをプレビューしてみます。

AppleのドキュメントではRectangle Viewをそれぞれ完全に重ならないように配置しています。

import SwiftUI

struct ContentView: View {
    let colors: [Color] =
        [.red, .orange, .yellow, .green, .blue, .purple]

    var body: some View {
        ZStack {
            ForEach(0..<colors.count) {
                Rectangle()
                    .fill(colors[$0])
                    .frame(width: 100, height: 100)
                    .offset(x: CGFloat($0) * 10.0,
                            y: CGFloat($0) * 10.0)
            }
        }
    }
}

プレビューはこんな感じです。

こっちの方がわかりやすいですね!!!!!!

f:id:dasuko:20210216233709p:plain

VStackとHStackを組み合わせてみる

最後にVStackHStackを組み合わせた場合を見ていきます。

次の例では水平方向に2つ、垂直方向に2つRectangleを配置しています。

import SwiftUI

struct ContentView: View {
    var body: some View {
        HStack {
            VStack {
                Rectangle()
                    .fill(Color.red)
                    .frame(width: 100, height: 100)
                
                Rectangle()
                    .fill(Color.orange)
                    .frame(width: 100, height: 100)
            }
            
            VStack {
                Rectangle()
                    .fill(Color.yellow)
                    .frame(width: 100, height: 100)
                
                Rectangle()
                    .fill(Color.green)
                    .frame(width: 100, height: 100)
            }
        }
    }
}

プレビューはこんな感になります。

f:id:dasuko:20210216234316p:plain

 

 

参考になったという方や、ここ間違っているよ!という方は

ぜひコメントしていただけると嬉しいです!!!!

 

SwiftUIを一から極めたいという人は本を買ってみるといいかも!

SwiftUIを本気でやろうとしていない人にはお勧めしません。

 

 

参考

Apple Developer Documentation