在 SwiftUI 中将 NavigationButton 与服务器请求一起使用

Use NavigationButton with a server request in SwiftUI

如何让 NavigationButton 在进入下一个视图之前等待服务器响应?

我试过这样的东西

NavigationButton(destination: LogonView(),  onTrigger: { () -> Bool in
                    return self.viewModel.responseReceived
                }) {
                    Text("OK")
                    }.tapAction {
                        self.viewModel.fetch(companyID: &self.companyID)
                }

但从未调用 tapAction

我使用 Button 使其工作:

Button(action: {
        self.viewModel.fetch(companyID: &self.companyID)
    }) {
        Text("OK")
    }.presentation(viewModel.shouldPresentModal ? Modal(LogonView() : nil)

    // in ViewModel
    var shouldPresentModal = false { // set to true when data are received from server
            didSet {
                didChange.send(())
            }
        }

但我需要在导航中显示下一个视图,而不是模态

谢谢!

Sorin,至少在我看来,SwiftUI 是专为表示层设计的,它不应该取代您的模型。而且它是 "reactive",与 UIKit 不同,因此从设计上讲,让视图执行 model-like 操作非常困难。

我会这样处理任务:

class LoginModel : BindableObject {

    var didChange = PassthroughSubject<LoginModel, Never>()

    private(set) var username: String? {
        didSet {
            didChange.send(self)
        }
    }

    func load() {
        DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
            self.username = "Sorin"
        }
    }
}

这是封装我们登录代码的模型对象。异步操作在这里通过一个简单的延迟来模拟。

然后是视图:

public struct LoginScreen: View {

    @ObjectBinding var loginObject = LoginModel()

    public var body: some View {
        Group {
            if login.username == nil {
                Text("Trying to login, please wait...")
            } else {
                Text("Successful login, the username is \(loginObject.username!)")
            }
        }.onAppear {
            self.loginObject.load()
        }
    }
}

模型对象有更好的 "linking" 方法,但显然我们这里只看 bare-bone 示例。

您的 NavigationButton 只会 link 登录屏幕,没有任何其他代码或触发器。 屏幕最初将显示 Trying to login, please wait...,5 秒后将变为 Successful login, the username is Sorin。显然你可以疯狂地用你想要的任何东西替换我这里的文字。