Swift UI生命周期:如何用新视图替换当前视图?不是简单地推动它



我在SwiftUI生命周期之后创建了一个SwiftUI应用程序。我可以毫无问题地推送新视图,但我不知道如何替换视图。我需要实现的是我在AppDelegate生命周期中使用此代码所能做的事情

let bounds = UIScreen.main.bounds
self.window = UIWindow(frame: bounds)
self.window?.rootViewController = rootViewController
self.window?.makeKeyAndVisible()

我试图替换根视图,并在推送新视图的同时忽略旧视图,但我找不到有效的解决方案。

我试着用

presentationMode.wrappedValue.dismiss()

但如果我在推出新观点之前或之后试图否定这种观点,那就行不通了。

我不知道我是不是错过了什么。

编辑

我尝试用ViewGroup 实现该解决方案

import SwiftUI
// Specify all root level screens
enum Screen {
case login
case users
}
@main
struct IosstarterkitApp: App {
var loginV: AnyView
var userV: AnyView
// Use @State for current screen
@State var screen: Screen = .login
init() {
// instantiate the factory for the dependency injection
let baseProviderFactory: BaseProviderProtocol = BaseProviderFactory()

// Create the SwiftUI views that provides the window contents.
var userView = UserView(store: UserStore())
userView.setPresenter(presenter: baseProviderFactory.getUserPresenter() as! BasePresenterProtocol)
userV = AnyView(userView)
var loginView = LoginView(store: LoginStore())
loginView.setPresenter(presenter: baseProviderFactory.getLoginPresenter() as! BasePresenterProtocol)
loginV = AnyView(loginView)
let userDefaultRepository = UserDefaultsRepository()
if userDefaultRepository.getAccessToken() != nil {
self.screen = .users
} else {
self.screen = .login
}
}
var body: some Scene {
WindowGroup {
switch screen {
case .login:
RootView(view: loginV)
case .users:
RootView(view: userV)
}
}
}
}

问题是,当我尝试根据令牌的存在来更新屏幕变量时,该变量没有得到更新。我试图根据用户登录的条件显示一个或另一个视图。此外,我需要从另一个文件中的另一个视图(如LoginView(更新屏幕变量。我该怎么做?

我看到您想要替换应用程序的根视图。以下是如何使用SwiftUI应用程序生命周期的简单示例:


import SwiftUI
// Specify all root level screens
enum Screen {
case onboarding
case home
}
@main
struct MyApp: App {
// Use @State for current screen
@State var screen: Screen = .onboarding
var body: some Scene {
WindowGroup {
switch screen {
case .onboarding:
OnboardingView {
screen = .home
}
case .home:
HomeView()
}
}
}
}
struct OnboardingView: View {
let openHome: () -> Void
var body: some View {
VStack {
Text("OnboardingView")
Button("Open Home") {
openHome()
}
}
}
}
struct HomeView: View {
var body: some View {
Text("HomeView")
}
}

您可以将MyApp: App视为SwiftUI中的常规View,在其中您可以使用state替换任何根视图。

编辑

这是代码的更新版本。它使用了非常基本的Coordinator实现。这里的Coordinator也是一个创建视图的工厂。有关更多高级信息,请搜索SwiftUI特定协调员的MVVM。


enum Screen {
case login
case users
}
final class AppCoordinator: ObservableObject {
@Published var screen: Screen = .login
private let userDefaultRepository = UserDefaultsRepository()
private let providerFactory: BaseProviderProtocol = BaseProviderFactory()
init() {
if userDefaultRepository.getAccessToken() != nil {
screen = .users
} else {
screen = .login
}
}
func userView() -> some View {
let store = UserStore()
let presenter = baseProviderFactory.getUserPresenter() as! BasePresenterProtocol
return UserView(store: store, presenter: presenter)
}
func loginView() -> some View {
let store = LoginStore()
let presenter = baseProviderFactory.getLoginPresenter() as! BasePresenterProtocol
return LoginView(store: LoginStore(), presenter: presenter)
}
}
@main
struct IosstarterkitApp: App {
@StateObject var coordinator = AppCoordinator()
var body: some Scene {
WindowGroup {
switch coordinator.screen {
case .login:
coordinator.loginView()
case .users:
coordinator.userView()
}
}
}
}

最新更新