ios – SwiftUI: Timer with start and stop not working

0
226


I have to animate after every 10 secs and I’m using Timer.publish and trying to stop timer if I push to another screen and start again timer on pops back to the same screen.

But even after cancel(), I can see logs in the sink method. Let me know the correct way to handle it.

struct MyView: View {
   
    @StateObject private var viewModel = QRCodeScanViewModel()
   
    var body: some View {
      parentView
         .onAppear {
            viewModel.playPulseAnimation()
         }
         .onDisappear(perform: viewModel.removePulseAnimation)
    }
}
final class MyAnimationClass: ObservableObject {
    
    private(set) var timer = Timer.publish(every: 10, tolerance: 0.5, on: .main, in: .common).autoconnect()
    
    @Published var shouldPlayPulseAnimation = false

    private var cancellables = Set<AnyCancellable>()

    init() {
     ..
     ...

        timer
            .sink(receiveValue: { [weak self] _ in
                print("TIMER SINK")
                self?.shouldPlayPulseAnimation = true
            })
            .store(in: &cancellables)
    }

    func playPulseAnimation(isFirstTime: Bool = false) {
        let delay: DispatchTime = .now() + (isFirstTime ? 15 : 0)
        print("playPulseAnimation:", delay)
        DispatchQueue.main.asyncAfter(deadline: delay) { [weak self] in
            guard let this = self else {
                return
            }
            this.timer = Timer.publish(every: 10, tolerance: 0.5, on: .main, in: .default).autoconnect()
        }
    }

    func removePulseAnimation() {
        print("removePulseAnimation")
        shouldPlayPulseAnimation = false
        timer.upstream.connect().cancel()
    }
}