问题
i have a timer in SwiftUI which works when opening the view for the first time. When navigating back and opening again, the timer does not start. Any idea what can be wrong ?
import SwiftUI
struct ClockDetail: View {
@State var seconds: Int = 0
@ObservedObject var motion: MotionManager
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
var body: some View {
VStack(alignment: .leading) {
Text("\(seconds)").font(.title).onReceive(timer) { output in
self.seconds += 1
}
Text("Attitude Data").foregroundColor(.blue)
Text("Roll: \(motion.roll)")
Text("Pitch: \(motion.pitch)")
Text("Yaw: \(motion.yaw)")
}.onDisappear(perform: {
self.timer.upstream.connect().cancel()
})
}
}
struct ClockDetail_Previews: PreviewProvider {
static var previews: some View {
ClockDetail(motion: MotionManager())
}
}
I'm using the .onDisappear to cancel the timer but seems that doesn't do the job.
回答1:
Your ClockDetail
is created only once, so once you invalidate timer it does not work anymore when you navigate again, because view is the same, but already w/o timer.
With the introduction of view model, as in below demo approach, it is better manageable I assume.
Tested with Xcode 11.2 / iOS 13.2. Note, I commented dependencies on not available entities, as they are not important for considered issue.
class ClockDetailViewModel: ObservableObject {
@Published var seconds = 0
private var subscriber: AnyCancellable?
func setup() {
self.seconds = 0
self.subscriber = Timer
.publish(every: 1, on: .main, in: .common)
.autoconnect()
.sink(receiveValue: { _ in
self.seconds += 1
})
}
func cleanup() {
self.subscriber = nil
}
}
struct ClockDetail: View {
@State private var seconds: Int = 0
// @ObservedObject var motion: MotionManager
@ObservedObject private var vm = ClockDetailViewModel()
var body: some View {
VStack(alignment: .leading) {
Text("\(vm.seconds)").font(.title)
Text("Attitude Data").foregroundColor(.blue)
// Text("Roll: \(motion.roll)")
// Text("Pitch: \(motion.pitch)")
// Text("Yaw: \(motion.yaw)")
.onAppear {
self.vm.setup()
}
.onDisappear {
self.vm.cleanup()
}
}
}
}
来源:https://stackoverflow.com/questions/60588413/swiftui-timer-not-firing-after-navigating-back