今回はレイアウトの基本HStack, VStack, XStackです. それぞれ横, 縦, 重ねるためのものになります.
環境は,
- macOS Catalina 10.15.6
- Xcode 12.0
- Swift 5.3
- iOS 14.0
です.
HStack
VStackはViewトを横に並べて表示します.
import SwiftUI
struct ContentView: View {
var body: some View {
HStack{
Text("A").font(.largeTitle)
Text("B").font(.largeTitle)
Text("C").font(.largeTitle)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}

SubViewの間隔をspacingで調整できます.
import SwiftUI
struct ContentView: View {
var body: some View {
HStack(spacing: 100) {
Text("A").font(.largeTitle)
Text("B").font(.largeTitle)
Text("C").font(.largeTitle)
}
}
}

VStack
VStackはViewを縦に並べて表示します.
コードも先ほどのHStackと一文字しか変わりません.
import SwiftUI
struct ContentView: View {
var body: some View {
VStack{
Text("A").font(.largeTitle)
Text("B").font(.largeTitle)
Text("C").font(.largeTitle)
}
}
}

ZStack
ZStackはViewを重ねて表示します.
コードも先ほどのHStack, VStackと一文字しか変わりません. (コード載せる必要すらありませんね.)
import SwiftUI
struct ContentView: View {
var body: some View {
ZStack{
Text("A").font(.largeTitle)
Text("B").font(.largeTitle)
Text("C").font(.largeTitle)
}
}
}

複雑なレイアウト
今までの例でわかるように, HStack, VStack, ZStackはデフォルトで中心に並びます. また, これらを組み合わせることによって複雑なレイアウトも実装できます.
import SwiftUI
struct ContentView: View {
var body: some View {
VStack{
HStack{
Text("A").font(.largeTitle)
Text("B").font(.largeTitle)
Text("C").font(.largeTitle)
}
HStack{
Text("D").font(.largeTitle)
Text("E").font(.largeTitle)
Text("F").font(.largeTitle)
}
HStack{
Text("G").font(.largeTitle)
Text("H").font(.largeTitle)
Text("I").font(.largeTitle)
}
}
}
}

ForEachを使うと格子状の配置も簡単に作成できます.
import SwiftUI
struct ContentView: View {
var body: some View {
VStack{
ForEach(0..<8) {_ in
HStack{
ForEach(0..<5) {_ in
Text("ABC")
.font(.title)
}
}
}
}
}
}

alignmentでのレイアウトの調整
HStack, VStack, ZStackはどれもalignmentプロパティを持っています. alignmentで位置を調整することができます.
値 | 説明 |
---|---|
.center | 中央揃え |
.top | 上揃え |
.bottom | 下揃え |
.leading | 左揃え |
.trailing | 右揃え |
HStackでalignmentを使用
横の配置ですので, center, top, bottomの選択が可能です.
import SwiftUI
struct ContentView: View {
var body: some View {
HStack(alignment: .top){
Text("ABC")
.background(Color.blue)
Text("DEFGH")
.font(.largeTitle)
.background(Color.green)
}
}
}



VStackでalignmentを使用
縦の配置ですので, center, leading, trailingの選択が可能です. Vstackもほとんど変わりませんので, コードは割愛します.



ZStackでalignmentを使用
center, top, bottom, leading, trailingすべての選択が可能です. 文字が重なっているのでわかりにくいですが, ABCの上にDEFGHがのっています.
import SwiftUI
struct ContentView: View {
var body: some View {
ZStack(alignment: .center){
Text("ABC")
.background(Color.blue)
Text("DEFGH")
.font(.largeTitle)
}
}
}





実は10個まで?
VStackやHStackはViewを10個までしか並べられません. 10個以上並べようとするとエラーになります.
VStackやHStackを使って複数のコントロールを並べられることがわかったところで「よし、もっともっとたくさん並べてみよう」と試してみた人もいるかもしれませんね。すると、ちょっと予想外なことになります。ただTextを並べていくだけなのに、ある時点でいきなりエラーになり動かなくなるのです。
実をいえばSwiftUlでは、コンテナに組み込めるコントロールは最大10個までなのです。それ以上は組み込めません。
掌田 津耶乃著 iOS/macOS UIフレームワーク SwiftUIプログラミング(2020/05/26発売) P.68より抜粋
ViewBuilder型の定義が10個までしか許容していないからですかね…
例えば以下のコードはエラーになります.
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Text("ABC_1")
Text("ABC_2")
Text("ABC_3")
Text("ABC_4")
Text("ABC_5")
Text("ABC_6")
Text("ABC_7")
Text("ABC_8")
Text("ABC_9")
Text("ABC_10")
Text("ABC_11")
}
}
}

ForEachを使えば, 15個でビルトできました.
import SwiftUI
struct ContentView: View {
var body: some View {
VStack{
ForEach(0..<15) {index in
Text("ABC_\(index)")
.font(.largeTitle)
}
}
}
}

どうやら回避方法はいろいろありそうです.
コメント