我不清楚您的示例是否需要一个计时器,但由于存在大量关于如何在 SwiftUI 应用程序中包含计时器的错误信息,我将进行演示。
关键是将计时器放在其他地方并在每次触发时发布。我们可以通过添加一个类来轻松地做到这一点,该类将计时器作为可绑定对象添加到我们的环境中(请注意,您将需要导入合并):
class TimerHolder : BindableObject {
var timer : Timer!
let didChange = PassthroughSubject<TimerHolder,Never>()
var count = 0 {
didSet {
self.didChange.send(self)
}
}
func start() {
self.timer?.invalidate()
self.count = 0
self.timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) {
[weak self] _ in
guard let self = self else { return }
self.count += 1
}
}
}
我们需要通过环境向下传递此类的实例,因此我们修改场景委托:
window.rootViewController =
UIHostingController(rootView: ContentView())
becomes
window.rootViewController =
UIHostingController(rootView: ContentView()
.environmentObject(TimerHolder()))
最后,让我们建立一些启动计时器并显示计数的 UI,以证明它正在工作:
struct ContentView : View {
@EnvironmentObject var timerHolder : TimerHolder
var body: some View {
VStack {
Button("Start Timer") { self.timerHolder.start() }
Text(String(self.timerHolder.count))
}
}
}
EDIT对于那些没有关注情节的人来说,更新:BindableObject 已迁移到 ObservableObject,并且不再需要手动发送信号。所以:
class TimerHolder : ObservableObject {
var timer : Timer!
@Published var count = 0
// ... and the rest is as before ...