SwiftUI:如何在取消计时器后重新启动计时器? [英] SwiftUI: How do you restart a timer after cancelling it?
问题描述
我有一个由主 ContentView 和 TimerView 组成的导航视图.当我调用 self.timer.upstream.connect().cancel()
.
I have a navigation view consisting of the main ContentView and a TimerView. The TimerView has a timer which correctly increments and also correctly stops when I call self.timer.upstream.connect().cancel()
.
但是,当我返回ContentView然后再次导航到TimerView时,我希望计时器重新开始计数,但是这不会发生. secondsElapsed
确实重置为0,但计时器不运行.
However when I go back to ContentView and then navigate to TimerView again, I want the timer to start counting again however this does not happen. secondsElapsed
does reset to 0 but the timer doesn't run.
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink(destination: TimerView()) {
Text("Go to Timer View")
}
}
}
}
struct TimerView: View {
@State var secondsElapsed = 0
var timer = Timer.publish (every: 1, on: .main, in: .common).autoconnect()
var body: some View {
VStack {
Text("\(self.secondsElapsed) seconds elapsed")
Button("Stop timer",
action: {
self.timer.upstream.connect().cancel()
})
}.onReceive(timer) { _ in
self.secondsElapsed += 1
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
推荐答案
据我所知(以及历史记录),在取消或无效后无法重新启动Timer.
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
}
}
这篇关于SwiftUI:如何在取消计时器后重新启动计时器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!