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

时间:2019-06-14 09:43:37

标签: ios swift 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(())
            }
        }

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

谢谢!

1 个答案:

答案 0 :(得分:2)

Sorin,至少在我的理解中,SwiftUI仅是为表示层设计的,不应替换您的模型。而且它与UIKit不同,它是“反应性的”,因此,设计使视图执行类似模型的动作非常困难。

我将执行以下任务:

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

有更好的方法与模型对象“链接”,但显然,这里我们仅看一个简单的例子。

您的NavigationButton仅链接到LoginScreen,而没有任何其他代码或触发器。 屏幕最初将显示Trying to login, please wait...,并在5秒钟后变为Successful login, the username is Sorin。显然,您可能会发疯,并用任何您想要的内容替换我的文字。