我有一个定时器的代码,它会自动启动,并且应该用if语句再次停止。不幸的是,这不起作用,我也没有收到错误信息。我在这里做错什么了?
import SwiftUI
import Combine
import Foundation
class WaitingTimerClass: ObservableObject {
@Published var waitingTimerCount: Int = 0
var waitingTimer = Timer()
func start() {
self.waitingTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in self.waitingTimerCount += 1 } }
func stop() { waitingTimer.invalidate() }
func reset() { waitingTimerCount = 0; waitingTimer.invalidate() }
}
struct ContentView: View {
@ObservedObject var observed = WaitingTimerClass()
var body: some View {
Text("\(self.observed.waitingTimerCount)")
.onAppear {
self.observed.start()
if self.observed.waitingTimerCount == 3 {
self.observed.stop()
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
``发布于 2020-02-27 11:40:20
onAppear块中的代码只工作一次,当View出现时(或多次,当视图消失并再次出现时)。在您的例子中,waitingTimerCount将始终是0。如果您需要从视图中观察一些值,请使用onReceive。代码应该如下所示:
struct TimerWaiter: View {
@ObservedObject var observed = WaitingTimerClass()
var body: some View {
Text("\(self.observed.waitingTimerCount)")
.onAppear {
self.observed.start()
}
.onReceive(observed.$waitingTimerCount) { count in
guard count == 3 else { return }
self.observed.stop()
}
}
}更新的第一作者的评论:我不知道,为什么重发计时器没有工作的预期,我今天没有太多的时间。也许明天会更容易理解。这里不是很好,但有效的解决方案:
class WaitingTimerClass: ObservableObject {
@Published var waitingTimerCount: Int = 0
var didInvalidate = PassthroughSubject<Void, Never>()
var waitingTimer = Timer()
func start() {
self.waitingTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in self.waitingTimerCount += 1 } }
func stop() { waitingTimer.invalidate() }
func reset() {
waitingTimer.invalidate()
waitingTimerCount = 0
didInvalidate.send()
}
}
struct TimerWaiter: View {
@ObservedObject var observed = WaitingTimerClass()
@State private var count = 0
var body: some View {
Text("\(count)")
.onAppear {
self.observed.start()
}
.onReceive(observed.$waitingTimerCount) { count in
self.count = count
guard count == 3 else { return }
self.observed.reset()
}
.onReceive(observed.didInvalidate) { _ in
self.count = 0
}
}
}P.S.我将尝试更深入地了解为什么waitingTimerCount的最后一次变化不会影响视图
发布于 2020-02-27 11:36:08
.onAppear {
self.observed.start()
if self.observed.waitingTimerCount == 3 {
self.observed.stop()
}
}这段代码是如何工作的?
当视图出现时它正在运行(很可能只有一次)
所以,就像你已经知道的,它永远不会停止。
如果您想停止waitingTimer == 3,则必须在您的模型中这样做。
@Published var waitingTimerCount: Int = 0 {
willSet {
if newValue == 3 { stop() }
}
}发布于 2020-03-01 17:57:50
非常感谢。重置问题的解决方案可以在这里找到:
https://stackoverflow.com/questions/60432112
复制相似问题