向后导航后,Swiftui计时器未触发

时间:2020-03-08 14:19:36

标签: xcode timer swiftui

我在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取消计时器,但似乎无法完成工作。

1 个答案:

答案 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()
            }
        }
    }
}