如何使用 SwiftUI 以编程方式转换视图?

Kev*_*vin 5 swift swiftui

我想在登录成功时向用户显示另一个视图,否则留在该视图上。我已经通过执行转场使用 UIKit 做到了这一点。SwiftUI 中有这样的替代方案吗?

NavigationButton 解决方案不起作用,因为我需要在转换到另一个视图之前验证用户输入。

Button(action: {
    let authService = AuthorizationService()
    let result = authService.isAuthorized(username: self.username, password: self.password)
    if(result == true) {
        print("Login successful.")
        // TODO: ADD LOGIC
        *** HERE I WANT TO PERFORM THE SEGUE ***

        presentation(MainView)
    } else {
        print("Login failed.")
    }
}) {
    Text("Login")
}
Run Code Online (Sandbox Code Playgroud)

Bog*_*rca 2

您可以根据响应执行如下操作(它像 Playground 一样打包以便于测试:

import SwiftUI
import Combine
import PlaygroundSupport


struct ContentView: View {
    var body: some View {
        NavigationView {
            MainView().navigationBarTitle(Text("Main View"))
        }
    }
}

struct MainView: View {
    let afterLoginView = DynamicNavigationDestinationLink(id: \String.self) { message in
        AfterLoginView(msg: message)
    }

    var body: some View {
        Button(action: {
            print("Do the login logic here")
            self.afterLoginView.presentedData?.value = "Login successful"
        }) {
            Text("Login")
        }
    }
}

struct AfterLoginView: View {
    let msg: String

    var body: some View {
        Text(msg)
    }
}

PlaygroundPage.current.liveView = UIHostingController(rootView: ContentView())
Run Code Online (Sandbox Code Playgroud)

尽管这可行,但我认为,从架构角度来看,您尝试将“命令式编程”范例推入 SwiftUI 的反应式逻辑中。我的意思是,我宁愿将登录逻辑包装到ObjectBinding具有公开isLoggedin属性的类中来实现它,并使 UI 对当前状态(由 表示isLoggedin)做出反应。

这是一个非常高级的示例:

struct MainView: View {
    @ObjectBinding private var loginManager = LoginManager()

    var body: some View {
        if loginManager.isLoggedin {
            Text("After login content")
        } else {
            Button(action: {  
                 self.loginManager.login()
            }) {
                 Text("Login")
            }
        }
    }
}

Run Code Online (Sandbox Code Playgroud)