SwiftUI の VStack・HStack・ZStack で画面を組み立てる
SwiftUI のレイアウトは、3 つのスタックコンテナを組み合わせて構築します。VStack は子ビューを縦方向に、HStack は横方向に、ZStack は奥行き方向に重ねて配置するコンテナです。
VStack:縦に並べる
VStack は子ビューを上から下へ順番に積み重ねます。フォームやリスト風の画面を組むときの基本となるコンテナです。
VStack(alignment: .leading, spacing: 12) {
Text("タイトル")
.font(.headline)
Text("サブタイトル")
.font(.subheadline)
Text("本文テキストがここに入ります")
.font(.body)
}alignment パラメータで子ビューの水平方向の揃え位置を指定できます。デフォルトは .center ですが、テキスト主体の画面では .leading を指定することが多いでしょう。spacing パラメータを省略すると、システムが各ビュー間に適切な間隔を自動で設定してくれます。
HStack:横に並べる
HStack は子ビューを左から右へ並べます。アイコンとテキストの横並びや、ボタンを横一列に配置するケースで活躍します。
HStack(spacing: 8) {
Image(systemName: "star.fill")
.foregroundColor(.yellow)
Text("お気に入り")
Spacer()
Text("12件")
.foregroundColor(.secondary)
}HStack の alignment パラメータは垂直方向の揃え位置を制御します。デフォルトは .center で、高さの異なるビューが混在しても中央揃えで統一されます。.firstTextBaseline を指定すると、フォントサイズが異なるテキスト同士をベースラインで揃えることもできます。
ZStack:重ねて配置する
ZStack は子ビューを同じ位置に重ねて描画します。先に書いた子ビューが奥に、後に書いた子ビューが手前に表示される仕組みです。
ZStack(alignment: .bottomTrailing) {
Image("background")
.resizable()
.aspectRatio(contentMode: .fill)
Text("NEW")
.font(.caption)
.padding(6)
.background(Color.red)
.foregroundColor(.white)
.cornerRadius(4)
.padding(8)
}背景画像の上にバッジを重ねるといった表現に適しています。alignment を .bottomTrailing にすると、手前のビューが右下に寄るため、通知バッジのような配置が簡単に実現できます。
スタックの組み合わせ
実際のアプリでは、3 種類のスタックをネストして複雑なレイアウトを構成します。カード型の UI を例に見てみましょう。
VStack(alignment: .leading, spacing: 8) {
HStack {
Image(systemName: "person.circle.fill")
.font(.title)
VStack(alignment: .leading) {
Text("田中太郎")
.font(.headline)
Text("3時間前")
.font(.caption)
.foregroundColor(.secondary)
}
Spacer()
}
Text("SwiftUI のスタックを使えば、宣言的にレイアウトを組み立てられます。")
.font(.body)
}
.padding()
.background(Color(.systemBackground))
.cornerRadius(12)
.shadow(radius: 2)VStack の中に HStack を入れ、さらにその中に VStack をネストしています。このようにスタックを入れ子にしていくことで、どんなに複雑な画面でも段階的に構築できます。
Auto Layout の制約をビュー間に設定し、位置関係を定義していく。制約の数が増えるとコンフリクトの管理が複雑になりやすい
スタックの入れ子で構造を宣言的に記述する。親子関係が明確で、コードの見た目とレイアウトの構造が一致しやすい
スタックは SwiftUI レイアウトの最も基本的な構成要素です。まずはこの 3 つのコンテナを自在に使いこなせるようになることが、SwiftUI でのアプリ開発の第一歩になります。