我有以下计时器:
struct ContentView: View {
@State var timeRemaining = 10
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
var body: some View {
NavigationView{
VStack {
if(self.timeRemaining > 0) {
Text("\(timeRemaining)")
.onReceive(timer) { _ in
if self.timeRemaining > 0 {
self.timeRemaining -= 1
}
}
} else {
Text("Time is up!")
}
}
}
}
}
如果我删除 NavigationView
View ,计时器会更新并工作,但就像那样它不会,这里发生了什么以及我如何在 NavigationView中更新它
?或者有更好的做法吗?
谢谢
最佳答案
最好将观察者附加到非条件 View ,比如
var body: some View {
NavigationView{
VStack {
if(self.timeRemaining > 0) {
Text("\(timeRemaining)")
} else {
Text("Time is up!")
}
}
.onReceive(timer) { _ in // << to VStack
if self.timeRemaining > 0 {
self.timeRemaining -= 1
}
}
}
}
更新:添加了一些想法(当然 SwiftUI 内部结构仅供 Apple 使用)。
.onReceive 必须附加到 NavigationView 中持续存在的 View ,原因很可能是在条件 ViewBuilder 和 UIKit UINavigationControler 周围的 NavigationView 包装器内部。
if you remove the condition and have a single Text view with onReceive inside the VStack inside the NavigationView, nothing is ever received
如果条件移除后它附加到 Text("\(timeRemaining)")
则一切正常(使用 Xcode 11.4 测试),因为主体中存在状态依赖性。
如果它附加到常量文本,那么主体没有任何变化,即。依赖于变化的状态 - timeRemaining
,因此 SwiftUI 渲染引擎将 body 解释为静态。
关于swift - 计时器 onReceive 在 NavigationView 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61378755/