这听起来像是一个微不足道的任务,但我找不到解决这个问题的正确方法。可能我还没有内化“SwiftUI-ish”的思维方式。
我有一个带有按钮的视图。当视图加载时,有一个条件(已经登录?),在该条件下视图应该直接转到下一个视图。如果单击该按钮,则会触发 API 调用(登录),如果成功,还会重定向到下一个视图。
我的尝试是建立一个模型(ObservableObject)来保存变量“shouldRedirectToUploadView”,它是一个 PassThroughObject。一旦满足视图中的 onAppear 条件或单击按钮(并且 API 调用成功),该变量就会翻转为 true 并告诉观察者更改视图。
翻转模型中的“shouldRedirectToUploadView”似乎有效,但我无法使视图重新评估该变量,因此新视图将无法打开。
这是到目前为止我的实现:
该模型
import SwiftUI
import Combine
class SboSelectorModel: ObservableObject {
var didChange = PassthroughSubject<Void, Never>()
var shouldRedirectToUpdateView = false {
didSet {
didChange.send()
}
}
func fetch(_ text: String) {
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
self.shouldRedirectToUpdateView = true
}
}
}
Run Code Online (Sandbox Code Playgroud)
风景
import SwiftUI
struct SboSelectorView: View {
@State var text: String = ""
@ObservedObject var model: SboSelectorModel
var body: some View {
return ZStack {
if (model.shouldRedirectToUpdateView) {
UpdateView()
}
else {
Button(action: {
self.reactOnButtonClick()
}) {
Text("Start")
}
}
}.onAppear(perform: initialActions)
}
public func initialActions() {
self.model.shouldRedirectToUpdateView = true
}
private func reactOnButtonClick() {
self.model.fetch()
}
}
Run Code Online (Sandbox Code Playgroud)
在旧的 UIKit 中,我只会使用 ViewController 来捕获按钮单击的操作,然后将新视图放在导航堆栈上。我该如何在 SwiftUI 中做到这一点?
在上面的示例中,我希望加载视图,执行onAppear()函数,该函数执行initialActions()来翻转模型变量,这将使视图对更改做出反应并呈现UploadView。为什么事情没有那样发生呢?
有这样的示例,例如以编程方式导航到 SwiftUI 中的新视图或通过按下 Swift UI 按钮显示新视图或如何在 SwiftUI 中使用 URLSession 发出请求后呈现视图?这表明相同的程序。然而它似乎对我不起作用。我错过了什么吗?
先感谢您!
苹果已经推出了@Published它可以完成所有的model did change事情。
这对我有用,而且看起来干净多了。
当模型中的某些内容发生变化时,您还可以用来.onReceive()在视图上执行某些操作。
class SboSelectorModel: ObservableObject {
@Published var shouldRedirectToUpdateView = false
func fetch(_ text: String) {
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
self.shouldRedirectToUpdateView = true
}
}
}
struct UpdateView: View {
var body: some View {
Text("Hallo")
}
}
struct SboSelectorView: View {
@State var text: String = ""
@ObservedObject var model = SboSelectorModel()
var body: some View {
ZStack {
if (self.model.shouldRedirectToUpdateView) {
UpdateView()
}
else {
Button(action: {
self.reactOnButtonClick()
}) {
Text("Start")
}
}
}.onAppear(perform: initialActions)
}
public func initialActions() {
self.model.shouldRedirectToUpdateView = true
}
private func reactOnButtonClick() {
self.model.fetch("")
}
}
Run Code Online (Sandbox Code Playgroud)
我希望这有帮助。
编辑
所以这似乎在beta 5中发生了变化
这是一个工作模型PassthroughSubject:
class SboSelectorModel: ObservableObject {
let objectWillChange = PassthroughSubject<Bool, Never>()
var shouldRedirectToUpdateView = false {
willSet {
objectWillChange.send(shouldRedirectToUpdateView)
}
}
func fetch(_ text: String) {
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
self.shouldRedirectToUpdateView = true
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6943 次 |
| 最近记录: |