从SwiftUI函数返回已填充的VStack

时间:2020-01-09 10:57:08

标签: swiftui

我想从函数,文本或文本和按钮的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之类的视图容器?

3 个答案:

答案 0 :(得分:7)

使用类型擦除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")
    })
}

答案 1 :(得分:6)

实际上,您接近解决方案。实际上,您可以通过以下方式使用some View作为返回类型:

func buildResponseText2() -> some View {
    Group {
        if userData.success {
            VStack {
                Text("Well Done")
                Button("Play Again", action: {self.userData.reset()})
            }
        } else {
            Text("Unlucky")
        }
    }
}

答案 2 :(得分:1)

提取布局并保留原始类型:

您应该使用自定义视图构建器实现自定义视图,以便您可以返回不同的类型。另外,您可能希望从返回值中删除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