Таймер Swiftui не срабатывает после навигации назад - PullRequest
1 голос
/ 08 марта 2020

У меня есть таймер в 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 Ответ

1 голос
/ 08 марта 2020

Ваш 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()
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...