複数のアイテムを設定するために、VStack、HStack、ZStackを使ってレイアウトできます。
またLazyVStack, LazyHStackというのも新しく追加されました。
Stack
SwiftUIのTextやImageなどのviewは、個別のbody propertyでlayoutを記述します。
但し、body propertyは単一のviewしか返さないので
複数のviewを扱うためにStackを使います。
- VStack:
垂直方向に並べます。
- HStack:
水平方向に並べます。
- ZStack:
Viewを重ねることができます。
VStack
Projectを作成してHello Worldが記述されているところから
「Text」を選択してCommand + クリックでActions ダイアログを表示
「Embed in VStack」を選びます。
Text()がVStackで挟まれた状態になります
1 2 3 4 |
VStack { Text("Hello, world!") .padding() } |
このTextにもう1つTextを追加して垂直方向に並べてみましょう。
Xcodeの右上にある「+」アイコンをクリックし
「□」を選択するとContorl Viewsを選べるようになり、
そのなかにTextがあります。
TextをそのままEditorのHello Worldの下にドラッグ
この辺りは直接記述したほうが早い気がしますが、使い方として覚えておきましょう(但し、やり方が変更されることも多いです)
1 2 3 4 5 6 7 8 9 10 |
struct ContentView: View { var body: some View { VStack { Text("Hello World!") .padding() Text("Placeholder") .padding() } } } |
Previewで見ると文字列が垂直方向に並んで配置されました。
Code Editorの「VStack」を選択してInspectorからAlignmentの「左寄せ」を選ぶと
.leadingに設定されるのがわかります。
1 2 3 4 |
VStack(alignment: .leading) { Text("Hello") Text("Placeholder") } |
Previewでは2列の先頭が左に寄せられています。
HStack
VStackど同様の設定をしてみましょう
「Text」を選択してCommand + クリックでActions ダイアログを表示
「Embed in HStack」を選び、Text()をLibraryから追加します。
1 2 3 4 5 6 7 8 9 10 |
struct ContentView: View { var body: some View { HStack { Text("Hello World") .padding() Text("Placeholder") .padding() } } } |
Text(“Placeholder”) が横に並んでレイアウトされているのがわかります。
ZStack
VStackど同様の設定をしてみましょう
「Text」を選択してCommand + クリックでActions ダイアログを表示
「Embed in VStack」を選び、Circle()をLibraryから追加します。
Circle()をModifiresでサイズを指定します。ただこのままではText()がわからないのでCircle()にforegroundColorでオレンジ色をつけてみます
1 2 3 4 5 6 7 8 9 10 11 12 13 |
struct ContentView: View { var body: some View { ZStack{ Circle() .frame(width: 150, height: 150, alignment: .center) .foregroundColor(.orange) Text("Hello, world!") .padding() } } } |
円と文字列が重なりました。
LazyZStack/LazyHStack
Lazyというのは「怠惰な」という意味ですが、きっちり表示するデータを揃えているとメモリがいっぱいになるので、(いい加減に?)見えているところしか用意していないという機能のようです。
たとえばスクロールListなどで、たくさんのTextを読み込んでいきます。ただスクロールして見えなくなってしまうものも取り込んだままだとメモリを圧迫することになるので、適当に表示されているところだけにしてもいいじゃん的なことをやってくれるものです。
LazyVStackにはサンプルコードがあるのですが、ForEachの回数が少ないので効果がわかりませんでしが、回す回数を増やしてみるとどのようになるかわかります。
1 2 3 4 5 6 7 8 9 10 11 |
struct ContentView: View { var body: some View { ScrollView { VStack { ForEach(1...1000000000000, id: \.self) { Text("Row \($0)") } } } } } |
このコードではエラーとなります。
Previewのエラーではありますがいずれにしてもこれは使えないということです。
VStackをLazyVStackに変更
1 2 3 4 5 6 7 8 9 10 11 |
struct ContentView: View { var body: some View { ScrollView { LazyVStack { ForEach(1...1000000000000, id: \.self) { Text("Row \($0)") } } } } } |
とりあえずエラーにはならず、表示がされています。
LazyHStackも同様です。
ScrollView(.horizontal) と水平方向のスクロールに変更します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
let colors: [Color] = [.red, .orange, .yellow, .green, .blue, .purple] struct ContentView: View { var body: some View { ScrollView(.horizontal) { LazyHStack { ForEach(1...1000000000000, id: \.self) { Text("Row \($0)") } } } } } |
References:
SwiftUI Tutorials — Tutorials | Apple Developer Documentation
VStack – SwiftUI | Apple Developer Documentation
HStack – SwiftUI | Apple Developer Documentation
ZStack | Apple Developer Documentation
LazyVStack | Apple Developer Documentation
LazyHStack | Apple Developer Documentation