swiftui有条件地呈现一个视图或另一个视图

swiftui有条件地呈现一个视图或另一个视图,swiftui,Swiftui,对于不透明的返回,如这里的某些视图,它应该返回一种类型,因此使用组,如下所示 struct ContentView: View { @EnvironmentObject var demoModel: DemoModel var body: some View { //this works demoModel.isLoggedIn ? Text("logged in"):Text("logged out") //this does

对于不透明的返回,如这里的
某些视图
,它应该返回一种类型,因此使用
,如下所示

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()
    }
}

当您在另一个视图的主体中初始化一个视图(比如说
a
)时,所发生的事情是将a作为参数传递给编译器生成的一些特殊函数:在上下文中具有隐式函数调用的系统(在本例中,该视图的
主体
)称为“函数生成器”,它们可以定制为具有不同的行为。SwiftUI中使用的是
ViewBuilder
:它“收集”在主体中创建的所有视图,并将它们“合并”到一个视图中(这就是为什么
body
的返回类型是
some View

ViewBuilder
包含一些技巧,通过嵌入诸如“显示一个视图或另一个视图”之类的逻辑来处理语言构造,如
if
语句,但是,截至当前版本的Swift(5.2),它不支持大多数其他工具,如“if-let,guard-let,do-catch”。其中一些将在下一个Swift版本中提供

不支持的内容之一是三元运算符
?:
。在您的示例中,第一行起作用是因为您为
true
false
分支返回相同的值,但在第二行中,您返回了不同类型的视图,从而导致错误。请注意,在ViewBuilder上下文(
)中使用的相同逻辑工作正常:

组{
如果demoModel.isLoggedIn{
文本(“已登录”)
}否则{
LoginView()
}
}
这是因为
ViewBuilder
知道如何管理简单的
if
语句

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