从 SwiftUI 函数返回填充的 VStack
Posted
技术标签:
【中文标题】从 SwiftUI 函数返回填充的 VStack【英文标题】:Returning a populated VStack from a SwiftUI function 【发布时间】:2020-01-09 10:57:08 【问题描述】:我想从一个函数、一个文本或一个文本和一个按钮的 VStack 返回不同的视图。这是我的尝试之一:
func buildResponseText2() -> some View
if (userData.success)
return VStack
Text("Well Done")
Button("Play Again", action: self.userData.reset())
return VStack
Text("Unlucky")
这不编译,我得到错误
函数声明了一个不透明的返回类型,但其主体中的返回语句没有匹配的底层类型
有没有办法返回像 VStack 这样具有异构内容的视图容器?
【问题讨论】:
【参考方案1】:使用类型擦除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")
)
【讨论】:
【参考方案2】:实际上,您已经接近解决方案。实际上,您可以通过这种方式使用some View
作为返回类型:
func buildResponseText2() -> some View
Group
if userData.success
VStack
Text("Well Done")
Button("Play Again", action: self.userData.reset())
else
Text("Unlucky")
【讨论】:
感觉这可以说是比公认的答案更好的解决方案,尽管它们都很相似。避免必须将 if-else 内容的每个分支都包装在AnyView
中——减少视觉噪音和将来更改的代码【参考方案3】:
提取布局并保留原始类型:
您应该使用自定义视图构建器实现自定义视图,以便可以返回不同的类型。此外,您可能希望从返回值中删除 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
【讨论】:
以上是关于从 SwiftUI 函数返回填充的 VStack的主要内容,如果未能解决你的问题,请参考以下文章
在 ScrollView 中使用 GeometryReader 的 SwiftUI 布局
如何从 Mac OS 中的 SwiftUI 列表中删除底部/顶部项目填充