Reputation: 455
I have a workout timer that lets the user workout for 30 seconds & then break for 10 seconds. I have some visual aspects that represent this with some Text saying whether it's a break or a workout time. When the timer first starts it works good, but over time it drifts off & the text begins to be changed early then it should. I'm invalidating my timers once they are done, I can't see why I would be getting different results just because time has passed.
func start() {
centreText = "Workout"
Timer.scheduledTimer(withTimeInterval: 30, repeats: false) { timer in
timer.invalidate()
break()
}
}
func break() {
breatheText = "Break"
Timer.scheduledTimer(withTimeInterval: 10, repeats: false) { timer in
timer.invalidate()
start()
}
}
How I'm calling start:
.onAppear {
withAnimation(.workout(workDuration: 30, break: 10), {
start()
})
Workout Animation:
public static func workout(workDuration: Double, break: Double) -> Animation {
return Animation.easeInOut(duration: workDuration).delay(break).repeatForever(autoreverses: true)
}
Upvotes: 0
Views: 211
Reputation: 991
As views in SwiftUI are struct
s, it's best to use a configurator class
using ObservableObject
to update UI. Handle all the timers in this class and use a Published
variable that the view assigns to.
struct MyView: View {
@StateObject private var config = MyViewConfig()
var body: some View {
Text(config.message)
Button("Start", action: config.start)
}
}
private final class MyViewConfig: ObservableObject {
@Published private(set) var message = "Workout"
func start() {
// star timer and update message
message = "Workout"
}
func stop() {
// stop timer and update message
message = "Break"
}
}
Upvotes: 2