在 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
。显然你可以疯狂地用你想要的任何东西替换我这里的文字。
如何让 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
。显然你可以疯狂地用你想要的任何东西替换我这里的文字。