gpt4 book ai didi

swift - Publisher 内的 Publisher 不会触发 SwiftUi 重新渲染

转载 作者:行者123 更新时间:2023-12-05 05:07:04 27 4
gpt4 key购买 nike

我在 EnvironmentObject 中为我的应用创建了一个“状态”对象像这样:

class AppState: ObservableObject {
@Published var counter = Counter()
}

要将其添加到我的应用程序中,我使用:

window.rootViewController = UIHostingController(rootView: contentView.environmentObject(state))

计数器是后台任务

class Counter: ObservableObject {

@Published var amount: Double

var timer = Timer()

init() {
self.amount = 0.0
self.timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(setCoords), userInfo: nil, repeats: true)
}

@objc private func setCoords() {
DispatchQueue.main.async() { () -> Void in
self.amount = self.amount + 0.1
print(self.amount)
}
}
}

在我看来我有:

struct ContentView: View {

@EnvironmentObject var state: AppState
@State var isVisible = true

var body: some View {
VStack {
Button(action: {
self.isVisible.toggle()
}) {
Text("Button")
}
if isVisible {
Text(state.counter.amount.description)
}
}
}
}

所以基本上,我希望每秒都能在我的 UI 更新中看到计数器。但是用户界面没有更新。我看到打印语句每秒触发一次,如果我从 UI 按钮 self.isVisible.toggle() 触发 UI 更新,那么计数器也会更新。

如果不将计数器移动到 View 中或在状态对象中实现它,我如何解决这个问题?

最佳答案

您的假设不正确。您将 Counter 设为 ObservableObject,但从未观察到它。

state 设置为 @EnvironmentObject 您会观察到属性 var counter 的变化,但不会在其中观察到。它是类、引用类型,而不是结构,因此对实例内部属性的修改不会导致实例本身的修改 - 引用保持不变,因此 state 没有改变。

这是使快照工作的方法之一 - 通过引入显式发布者事件来观察和更新相关的本地 View 状态:

@State var currentCounter: String = ""
var body: some View {
VStack {
Button(action: {
self.isVisible.toggle()
}) {
Text("Button")
}
if isVisible {
Text(currentCounter)
.onReceive(state.counter.$amount, perform: { value in
self.currentCounter = value.description
})
}
}
}

关于swift - Publisher 内的 Publisher 不会触发 SwiftUi 重新渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59452113/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com