SwiftUIにおけるHStack、VStack、ZStackとは何かを解説します — すべてのAppleプラットフォームでユーザーインターフェースを構築するためのコンテナスタックです。HStackは要素を水平に、VStackは垂直に、ZStackは奥行き方向(オーバーレイ)に配置します。スタックはSwiftUIの基盤であり、どのビューもalignmentとspacingパラメータを持つネストされたスタックから構築されます。Apple WWDC 2024によると、SwiftUIアプリの90%以上の画面がこれら3つのスタックの組み合わせを使用しています。
重要ポイント
HStack(Horizontal Stack)は、子ビューを水平方向に並べるSwiftUIコンテナです。各子要素は、特に指定がない限り必要なスペースを取ります。HStackは2つの必須パラメータを受け付けます: alignment(垂直方向のアライメント、デフォルトは.center)とspacing(要素間の距離、デフォルトはnil — システム間隔)。Apple Human Interface Guidelines(2025)によると、HStackはボタンバー、入力行、水平アイコンリストに推奨される選択肢です。
HStack(alignment: .center, spacing: 16) {
Image("star")
.resizable()
.frame(width: 24, height: 24)
Text("お気に入り")
.font(.body)
Spacer()
Image("chevron.right")
.foregroundColor(.gray)
}
.padding()
この例では、HStackが3つの要素(アイコン、テキスト、矢印)の行を作成します。Spacer()が要素を引き離し、アイコンとテキストは左端に、矢印は右端に配置されます。Alignment .centerは3つの要素すべてを垂直中心軸に沿って揃えます。
VStack(Vertical Stack)は、子要素を上から下へ垂直に配置するSwiftUIコンテナです。HStackと同様に、alignment(水平アライメント: .leading、.center、.trailing)とspacingを受け付けます。VStackはフォーム、カード、プロフィール、設定リストを構築するための基盤です。Apple Docs(2025)によると、VStackはLazyVStackと組み合わせてSwiftUIの垂直レイアウトシナリオの85%をカバーします。
VStack(alignment: .leading, spacing: 8) {
Text("レシピ名")
.font(.headline)
Text("調理時間: 30分")
.font(.subheadline)
.foregroundColor(.secondary)
HStack(spacing: 4) {
Image("star.fill")
.foregroundColor(.yellow)
Text("4.8")
}
}
alignment .leadingを指定したVStackは、すべての行を左端に揃えます。VStackの内部には評価用のHStackがネストされています — これはネストされたスタックを通じて複雑なレイアウトを構築する典型的なパターンです。Spacing 8はテキスト行間に均等な間隔を作ります。
ZStack(Z軸スタック)は、子ビューを奥行き軸に沿って互いに重ね合わせるSwiftUIコンテナです。ZStackの本体の最初の要素は背景に描画され、最後の要素は前景に描画されます。ZStackは、テキストが重なった背景画像、カスタムインジケーター、オーバーレイボタン、トランジションアニメーションに使用されます。Apple Docs(2025)によると、ZStackはデフォルトですべての要素を中央に揃えます(alignment: .center)が、任意のAlignmentの組み合わせをサポートします。
ZStack(alignment: .bottomLeading) {
Image("mountains")
.resizable()
.scaledToFill()
.frame(height: 200)
.clipped()
Color.black
.opacity(0.3)
Text("山の風景")
.font(.title)
.bold()
.foregroundColor(.white)
.padding()
}
この例では、ZStackが3つのレイヤーを重ねています: 山の画像、暗くするための半透明の黒色、タイトルテキストです。Alignment .bottomLeadingはテキストを左下隅に固定します。暗くする処理(Color.black.opacity(0.3))により、画像の明るい部分でのテキストの可読性が向上します。
スタックの選択はレイアウトの方向によって異なります: HStack — 水平配置(ボタン、入力行)、VStack — 垂直配置(フォーム、カード)、ZStack — 重ね合わせ(背景、オーバーレイ)。Apple Human Interface Guidelines(2025)によると、複雑なレイアウトではスタックが互いにネストされます: 外側のVStackの中にHStackとZStackが含まれます。LazyHStackとLazyVStackは大きなコレクション用の遅延バージョンです。
| スタック | 軸 | Default Alignment | 使用場面 | 遅延バージョン |
|---|---|---|---|---|
| HStack | 水平 | .center | ボタンバー、水平リスト | LazyHStack |
| VStack | 垂直 | .center | フォーム、プロフィール、カード | LazyVStack |
| ZStack | 奥行き(z) | .center | 重ね合わせ、背景、オーバーレイ、バッジ | なし |
alignmentとspacingパラメータは、SwiftUIスタック内の子要素の配置を完全に制御します。HStackのAlignmentは異なる高さの要素の垂直アライメントを制御します。VStack alignmentは水平アライメントを制御します。Spacingはスタック内のすべての子要素間の距離を設定します。SwiftUI Lab(2025)によると、alignmentは標準(.top、.center、.bottom)またはAlignmentIDによるカスタムが可能です。
HStack(alignment: .top, spacing: 12) {
Text("タイトル")
.font(.largeTitle)
VStack(alignment: .leading) {
Text("サブタイトル")
Text("追加テキスト付きの説明")
.font(.caption)
.foregroundColor(.gray)
}
}
.padding()
ここでは、alignment .topが大きなタイトルとネストされたVStackを上端に沿って揃えます。Spacing 12はそれらの間に間隔を作ります。alignment .leadingを持つネストされたVStackは、サブタイトルと説明を左端に揃えます。ネストされたスタック内で異なるalignmentを組み合わせることで、正確なレイアウト制御が可能になります。
実際のインターフェースは、ネストされたHStack、VStack、ZStackを組み合わせて構築されます。商品カードは典型的な例です: 外側のVStackには、画像(ZStackとオーバーレイ)、タイトル(Text)、評価(HStack)、価格が含まれます。Apple Sample Projects(2025)によると、スタックのネストの深さは4レベルを超えることはめったにありません — より深いネストはコードの可読性とパフォーマンスを低下させます。
VStack(spacing: 12) {
ZStack(alignment: .topTrailing) {
Image("product")
.resizable()
.scaledToFit()
Text("-20%")
.font(.caption)
.bold()
.foregroundColor(.white)
.padding(6)
.background(Color.red)
.cornerRadius(4)
}
Text("スマートフォン Model X")
.font(.headline)
HStack(spacing: 8) {
Text("$999")
.font(.title2)
.bold()
Spacer()
Image("star.fill")
.foregroundColor(.yellow)
Text("4.7")
}
}
.padding()
この例では、VStackがZStack(割引バッジ付き画像)、商品名、HStack(価格+評価)を結合しています。ZStackはalignment .topTrailingを使用して「-20%」バッジを右上隅に配置します。HStackのSpacerは価格を左端に、評価を右端に押しやります。
よくある質問
HStackは要素を水平に(左から右へ)配置し、VStackは垂直に(上から下へ)配置します。どちらもalignmentとspacingをサポートしています。HStackは垂直方向(top、center、bottom)に揃え、VStackは水平方向(leading、center、trailing)に揃えます。選択はレイアウトの方向によって異なります: ボタン行にはHStackを、フォームにはVStackを使用してください。
ZStackとoverlayは、重ね合わせに対する異なるアプローチです。ZStackはすべての子要素をレイアウトの等しい部分として結合します。Overlayは単一のビューにアタッチされ、それに合わせて拡張されます。SwiftUI Lab(2025)によると、overlayは単一のビューの上の小さな要素(バッジ、アイコン)に適しており、ZStackは完全なマルチコンポーネントのオーバーレイに適しています。
HStackには.frame(maxWidth: .infinity)修飾子を、VStackには.frame(maxHeight: .infinity)を使用します。HStack内のすべての子要素の幅を同じにするには、各要素に.frame(maxWidth: .infinity)を追加します。VStackの場合は、.fixedSize(horizontal: false, vertical: true)を使用して垂直サイズを強制します。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。