Search code examples
timerswiftuirestart

SwiftUI Timer restart after canceling


I'm still trying out timers and this works as well. The timer is exited after a certain time. But how can I restart it now? I'm grateful for any help. I suspect with .autoconnect (). But I don't really get it.

import SwiftUI

struct ContentView: View {

    @State private var timerHold = false
    @State var waitingTimerCount = 0
    let waiting = ["A","B","C",]
    let waitingTimer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

    var body: some View {
        VStack {
            Button(action: {
                self.timerHold = true
                 }) { Text("Button") }

        if timerHold == true {
            Text(verbatim: waiting[waitingTimerCount])
                .onReceive(waitingTimer) { timer in
                    self.waitingTimerCount = (self.waitingTimerCount + 1) % self.waiting.count
                        if self.waitingTimerCount == 3 {
                            self.timerHold = false
                            self.waitingTimerCount = 0
                            self.waitingTimer.upstream.connect().cancel()
                            }
                        }
                    }
                }
    }
}

//??
// self.waitingTimer.upstream.autoconnect()

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}



Solution

  • auto-connecting timer in playground

    import PlaygroundSupport
    import Combine
    import Foundation
    PlaygroundPage.current.needsIndefiniteExecution = true
    
    var cancellable: AnyCancellable?
    // start automatically
    cancellable = Timer.publish(every: 1, on: .main, in: .default)
        .autoconnect()
        .sink {
            print($0)
        }
    

    prints

    ...
    2020-02-24 02:22:20 +0000
    2020-02-24 02:22:21 +0000
    2020-02-24 02:22:22 +0000
    2020-02-24 02:22:23 +0000
    2020-02-24 02:22:24 +0000
    2020-02-24 02:22:25 +0000
    2020-02-24 02:22:26 +0000
    ...
    

    manually start / stop timer

    let timerPublisher = Timer.publish(every: 1.0, on: RunLoop.main, in: .default)
    cancellable = timerPublisher
        .sink {
            print($0)
        }
    
    /// ...
    
    // start publishing time
    let cancellableTimerPublisher = timerPublisher.connect()
    // stop publishing time
    cancellableTimerPublisher.cancel()