我想从函数、文本或文本和按钮的 VStack 返回不同的视图。这是我的尝试之一:
func buildResponseText2() -> some View {
if (userData.success) {
return VStack {
Text("Well Done")
Button("Play Again", action: {self.userData.reset()})
}
}
return VStack {
Text("Unlucky")
}
}
这不编译,我收到错误
函数声明不透明的返回类型,但其主体中的 return 语句没有匹配的基础类型
有没有办法返回像VStack这样具有异构内容的视图容器?
使用类型擦除AnyView
作为返回类型,如下所示
func buildResponseText2() -> AnyView {
if (userData.success) {
return AnyView(VStack {
Text("Well Done")
Button("Play Again", action: {self.userData.reset()})
})
}
return AnyView(VStack {
Text("Unlucky")
})
}
实际上,您已经接近解决方案了。实际上,您可以将该方法标记为ViewBuilder
,并通过以下方式使用some View
作为返回类型:
@ViewBuilder
func buildResponseText2() -> some View {
if userData.success {
VStack {
Text("Well Done")
Button("Play Again", action: {self.userData.reset()})
}
} else {
Text("Unlucky")
}
}
如果您愿意,还可以以相同的方式使用计算属性:
@ViewBuilder
var responseText2: some View {
if userData.success {
VStack {
Text("Well Done")
Button("Play Again", action: {self.userData.reset()})
}
} else {
Text("Unlucky")
}
}
提取布局并保留原始类型:
应使用自定义视图生成器实现自定义视图,以便可以返回不同的类型。此外,您可能希望从返回值中删除VStack
,以便以后可以决定使用其他布局,而无需更改内容。
所以实现这个:
struct StackContent: View {
let success: Bool
@ViewBuilder var body: some View {
switch success {
case true:
Text("Well Done")
Button("Play Again") { print("clicked") }
case false:
Text("Unlucky")
}
}
}
然后你可以有这个:
func buildResponseText2() -> some View {
VStak { // <- you can change it to other layout containers
StackContent(success: userData.success)
}
}
也许您根本不需要该功能了;)
请注意,没有必要从 Swift 5.3 (Xcode 12( 编写@ViewBuilder