I have a navigation view consisting of the main ContentView and a TimerView. The TimerView has a timer which correctly increments and also corr
To my knowledge (and historically), Timer cannot be restarted after cancellation or invalidation.
What I do is just re-declare the timer.
Here is an example with some added personal preferences:
struct TimerView: View {
@State var secondsElapsed = 0
@State var timer: Timer.TimerPublisher = Timer.publish (every: 1, on: .main, in: .common)
var body: some View {
VStack {
Text("\(self.secondsElapsed) seconds elapsed")
Button("Stop timer",
action: {
self.cancelTimer() // Just to be a little more DRY/maintenance-friendly, but personal preference.
})
}.onAppear(perform: {
self.instantiateTimer() // You could also consider an optional self.timer variable.
self.timer.connect() // This allows you to manually connect where you want with greater efficiency, if you don't always want to autostart.
}).onDisappear(perform: {
// I don't know your exact flow, but you said you want the timer to restart upon return navigation.
// So, I am just assuming you want to stop the timer when you navigate out.
// But, you can also easily remove this closure.
// Also, this may not run as you would intuit.
self.cancelTimer()
}).onReceive(timer) { _ in
self.secondsElapsed += 1
}
}
func instantiateTimer() {
self.timer = Timer.publish (every: 1, on: .main, in: .common)
return
}
func cancelTimer() {
self.timer.connect().cancel()
return
}
}