我在SwiftUI中有一个计时器,该计时器在首次打开视图时起作用。向后导航并再次打开时,计时器不会启动。知道有什么问题吗?
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())
}
}
我正在使用.onDisappear取消计时器,但似乎无法完成工作。
答案 0 :(得分:1)
您的ClockDetail
仅创建一次,因此,一旦使计时器失效,它就不再起作用,因为视图是相同的,但是已经没有计时器了。
随着视图模型的引入(如下面的演示方法所示),我认为它更易于管理。
通过Xcode 11.2 / iOS 13.2测试。注意,我评论了对不可用实体的依赖,因为它们对于考虑的问题并不重要。
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()
}
}
}
}