Reputation: 67
I'm building an app with SwiftUI with a stop watch functionality.
The TimedSession class has a var timer: Timer
computed property like this:
Timer.scheduledTimer(withTimeInterval: 0.01, repeats: true) { timer in
guard let time = self.currentTime else {
print("no current time")
return
}
if self.status != .running {
timer.invalidate()
return
}
time.duration += 1
self.objectWillChange.send()
}
this works well until I start to interact with other parts of the UI, like a scrollview. It's not just that the timer UI is locked, but the block: callbck on scheduledTimer isn't being executed.
What's the best way to put the callback block into the background? I've tried with GCD but no good so far.
Upvotes: 3
Views: 2491
Reputation: 258217
Scheduled Timer
works by default in .default
run loop mode, but during user interaction, like scrolling, a run loop works in different tracking mode.
The solution is set up Timer
for all standard modes, named .common
, like below
// just create non attached timer
let timer = Timer(timeInterval: 0.01, repeats: true) { timer in
guard let time = self.currentTime else {
print("no current time")
return
}
if self.status != .running {
timer.invalidate()
return
}
time.duration += 1
self.objectWillChange.send()
}
...
init() {
// Start timer in run-loop on common modes
RunLoop.main.add(timer, forMode: .common)
}
Upvotes: 3