【SwiftUI】 今日のなんでやねん - @ViewBuilder
@ViewBuilder
よく見かけますが、なんのために使うのか。
■ 公式ドキュメント - ViewBuilder
A custom parameter attribute that constructs views from closures.
クロージャから View を構築するカスタムパラメータ属性。
You typically use ViewBuilder as a parameter attribute for child view-producing closure parameters, allowing those closures to provide multiple child views.
通常、ViewBuilderを子 View 生成クロージャパラメータのパラメータ属性として使用し、それらのクロージャが複数の子 View を提供できるようにします。
func contextMenu<MenuItems: View>(
@ViewBuilder menuItems: () -> MenuItems
) -> some View
myView.contextMenu {
Text("Cut")
Text("Copy")
Text("Paste")
if isSymbol {
Text("Jump to Definition")
}
}
👉 ViewBuilder | Apple Developer Documentation
並列のまま、持ち運びできて、
記述が一層不要になるってことか。
■ if も使えるようになる
// NG
var body: some View {
if imageName.isEmpty {
return Text("no image")
} else {
return Text(imageName)
}
}
@ViewBuilder
var body: some View {
if imageName.isEmpty {
Text("no image")
} else {
Image(imageName)
}
}
var body: some View {
Group {
if imageName.isEmpty {
Text("no image")
} else {
Image(imageName)
}
}
}
👉 SwiftUIのViewで条件によってViewを出し分ける方法 - The Pragmatic Ball boy
そういえば、
公式ドキュメントのサンプルコードにも、
しれっと if が入っていた。
なるほど、
Group / VStack / HStack がなければ使えなかった if を使えるようにしてくれるのか。
便利そう !
■ やってみた
こういうのがあったとして、
VStack {
Text("top")
Text("bottom")
}
.font(.title)
.foregroundColor(.red)
こう書ける。
TitleTextFormatView1 {
Text("top")
Text("bottom")
}
struct TitleTextFormatView1<Content: View>: View {
@ViewBuilder var content: Content
var body: some View {
content
.font(.title)
.foregroundColor(.red)
}
}
続いて、@ViewBuilder を消してみます。
TitleTextFormatView2 {
Text("top")
Text("bottom")
}
struct TitleTextFormatView2<Content: View>: View {
// Type '() -> ()' cannot conform to 'View'
var content: Content // *
var body: some View {
content
.font(.title)
.foregroundColor(.red)
}
}
しかし、これは NG ですね、分かります。
勉強しましたから !
続きましては、
渡す View を VStack を使って、1つにまとめます。
他は変更ありません。
結果は、OK なはずです。
TitleTextFormatView3 {
VStack { // *
Text("top")
Text("bottom")
}
}
struct TitleTextFormatView3<Content: View>: View {
var content: Content
var body: some View {
content
.font(.title)
.foregroundColor(.red)
}
}
...
なんでや !?
■ まとめ
私はこれまで、
まず VStack や HStack を常に書いていたので
@ViewBuilder の必要性を感じなかった
ことが分かりました。
しかし、今回の結果は残念です。
謎です。
以下の基本的なキーワード、
「TupleView」
「Content」
「some View」
「any View」
「View | Stack | Layout」
分かりづらくないですか。
直感的にふんわりしてません ?
長い説明が必要ですよね ?
あなたの感想ですよね ?
【Android】「Navigation Bar」はどちらか分かりますか?
混乱しません?
👉 Window insets in Compose | Jetpack Compose | Android Developers
👉 Navigation bar – Material Design 3
ネーミングややこしくない?
最近の Android 界隈。