ZStackとbackground(overlay)修飾子の使い分けできてる?
この記事では、SwiftUIでUIを実装する時の ZStack
と background(overlay)修飾子
の使い分けについて整理していきます。
Componentを重ねてデザインを実装する
下記のようなUIをSwiftUIで実装する時に、どう実装しますか?
パッと思いつく方法だと下記の2つがありそうです。
ZStack {
Circle()
.fill(Color.CustomGreen)
.frame(width: 200, height: 200)
Text("Sample1")
.foregroundStyle(Color.white)
.font(.regular15)
}
Text("Sample1")
.foregroundStyle(Color.white)
.font(regular15)
.background(
Circle()
.fill(Color.CustomGreen)
.frame(width: 200, height: 200)
)
ビルドして表示してみると、どちらも同じ結果になり期待通りのUIを実装できています。
では、画面上に他のComponentがある場合はどうでしょうか?
画面上に他のComponentがある場合
例として、上記のUIの下に Text
を配置してみます。
VStack(spacing: 24) {
ZStack {
Circle()
.fill(Color.CustomGreen)
.frame(width: 200, height: 200)
Text("Sample1")
.foregroundStyle(Color.white)
.font(.regular15)
}
// Textを追加
Text("Sample2")
.foregroundStyle(Color.white)
.font(.regular15)
}
VStack(spacing: 24) {
Text("Sample1")
.foregroundStyle(Color.white)
.font(regular15)
.background(
Circle()
.fill(Color.CustomGreen)
.frame(width: 200, height: 200)
)
// Textを追加
Text("Sample2")
.foregroundStyle(Color.white)
.font(.regular15)
}
上記の実行結果はどうなるでしょうか?続きを読む前に予想してみてください。
クリックして、実行結果を確認
ZStackを使う | background修飾子を使う |
---|---|
実行結果が予想通りで、なぜそうなるのか説明できる方はこの先を読む必要はないです🙇♂️
ZStackとbackground(overlay)修飾子の違い
実行結果になぜこのような違いがあるかというと、実際のレイアウトを確認すると分かりやすいです。
クリックして、レイアウトを確認
ZStackを使う | background修飾子を使う |
---|---|
レイアウトからも分かる通り、VStack
のspacingや padding修飾子
を使うSwiftUIでのmargin設定では、background(overlay)修飾子で追加した要素は考慮されません。
「background(overlay)修飾子はあくまで修飾子なので、今回の例で言うとbackground修飾子で追加した Circle
はレイアウトを構成する要素としてカウントされていません。(テキストカラー等と同じ扱い)」
そのため今回の例では、
- ZStackを使った場合
-
「ZStackで実装した、円の中にテキストがあるView」 と「Sample2を表示しているText」との間に
VStack
のspacingが設定されます。
-
「ZStackで実装した、円の中にテキストがあるView」 と「Sample2を表示しているText」との間に
- background修飾子を使った場合
-
「Sample1を表示しているText」 と「Sample2を表示しているText」との間に
VStack
のspacingが設定されます。
-
「Sample1を表示しているText」 と「Sample2を表示しているText」との間に
このように整理すると、background(overlay)修飾子を使う機会がないように感じますが、下記のような場合はbackground(overlay)修飾子が有効です。
具体例を挙げると、テキストに背景色を追加する場合は下記のようにスッキリ書けます。
このように書くと、表示する文字列に合わせて Text
のサイズが変わりますが、その Text
サイズに合わせて背景色を指定できます。
Text("Sample1")
.foregroundStyle(Color.white)
.font(regular15)
.frame(width: 200, height: 200)
.background(
Color.CustomGreen
)
background(overlay)修飾子を使うときの注意点は
Text("Sample1")
.foregroundStyle(Color.white)
.font(regular15)
.frame(width: 200, height: 200) // 先にView側でサイズを指定する
.background(
Color.CustomGreen
)
最後に
この記事を書くにあたって、サンプルのコードを色々検討しつつ実装していて、SwiftUIは深く理解しなくてもほとんどのUIが実装できますが、 それぞれの特性をちゃんと理解して正しく実装することが大事 だなと実感しました。
Discussion