如何在不将视图嵌入到 SwiftUI 中的当前导航流中的情况下呈现视图?

How to present a View without embedding it into a current navigation flow in SwiftUI?

我正在完成一个日志记录,我需要展示一个 HomeView,它对之前的导航流程一无所知。

var body: some View {
    if viewModel.isValidated {
       destination()
    } else {
       LoadingView()
    }

这样做我在 destination() 的顶部有一个导航栏。我想我可以隐藏它,但它仍然是相同的导航流程,我需要开始一个新的。我怎样才能做到这一点?(iOS 13)

处理此问题的一种方法是使用从 BaseViewModel 创建的 @Environment 对象。它的工作方式本质上是从 BaseView 或视图控制器控制呈现视图的状态。我会尽力为您简化它。

class BaseViewModel: ObservableObject {
    @Published var baseView: UserFlow = .loading

    init() {
         //Handle your condition if already logged in, change 
         //baseView to whatever you need it to be. 
    }
    
    enum UserFlow {
        case loading, onboarding, login, home
    }
}

一旦你设置了你的 BaseViewModel,你就会想要使用它,我在一个 switch 语句中使用它并绑定到 @EnvironmentObject 以便它可以从任何其他视图进行更改。

struct BaseView: View {
    @EnvironmentObject var appState: BaseViewModel
    
    var body: some View {
        Group {
            switch appState.userFlow {
            case .loading:
                LoadingView()
            case .onboarding:
                Text("Not Yet Implemented")
            case .login:
                LandingPageView()
            case .home:
                BaseHomeScreenView().environmentObject(BaseHomeScreenViewModel())
            }
        }
    }
}

您的用法,很可能在您的 register/login 流程结束时,看起来像这样。

struct LoginView: View {

@EnvironmentObject var appState: BaseViewModel

    var body: some View {
        Button(action: {appState = .home}, label: Text("Log In"))
    }
}

所以基本上这里发生的事情是您将您的应用程序流存储在一个永远不会被处理的特定视图中。把它想象成一个容器。每当您更改它时,它都会更改您要呈现的特定视图。这样做的特别好处是,如果需要,您可以在不使用导航链接的情况下构建单独的导航层次结构。