swiftui有条件地渲染一个视图或另一个视图

时间:2020-06-03 08:49:32

标签: swiftui

struct ContentView: View {
    @EnvironmentObject var demoModel: DemoModel

    var body: some View {
        //this works
        demoModel.isLoggedIn ? Text("logged in"):Text("logged out")

        //this doesnt work why
        //demoModel.loggedIn ?  StationListView(): LoginView()
    }
}

2 个答案:

答案 0 :(得分:1)

对于不透明的返回,如此处的some View,应返回一种类型,因此请使用Group,如下所示

Group {
    if demoModel.loggedIn {
        StationListView()
    } else {
        LoginView()
    }
}

答案 1 :(得分:1)

当您在另一个View的主体中初始化一个View(例如A)时,会发生的事情是A作为参数传递给编译器生成的某些特殊函数:这种具有隐式函数调用的系统在上下文中(在这种情况下,此视图的body)被称为“函数构建器”,可以对其进行自定义以具有不同的行为。 SwiftUI中使用的是ViewBuilder:它“收集”您在正文中创建的所有视图并将它们“合并”到一个视图中(这就是body的返回类型为{{1 }}。

some View包含一些技巧,可通过嵌入诸如“显示一个视图或另一个视图”之类的逻辑来处理ViewBuilder语句之类的语言结构,但是,从当前版本的Swift(5.2)开始,它没有支持大多数其他工具,例如“如果放手,守卫,抓到”。其中一些将在下一个Swift版本中提供。

不支持的操作之一是三元运算符if。在您的示例中,第一行有效是因为您为?:true分支返回了相同的值,但是在第二行中,您返回的是不同类型的View,结果是错误。请注意,在ViewBuilder上下文(false)中使用的相同逻辑也很好:

Group

那是因为Group { if demoModel.isLoggedIn { Text("Logged in") } else { LoginView() } } 知道如何管理简单的ViewBuilder语句。