I'm trying to use two timers in the same SwiftUI view

one or the other works but not both
if the timers have the same interval it works

Code Block
struct ContentView: View {
    @State var isPlaying: Bool = true
    @State var timeRemaining: Int = 1800
    @State var count = 1
    @State var count2 = 10
    
    var body: some View {
        let timer2 = Timer.publish(every: 1, on: .main, in: .default).autoconnect()
        let timer = Timer.publish(every: 0.5, on: .main, in: .default).autoconnect()
        VStack {
            Text("\(count)    \(count2)")
                .padding()
        }
        .onReceive(timer2) { _ in
            if self.timeRemaining > 0 && isPlaying == true {
                self.count2 += 1
            }
        }
        .onReceive(timer) { _ in
            if self.timeRemaining > 0 && isPlaying == true {
                self.count += 1
            }
        }
    }
}

Replies


I tried your code and found the closure for onReceive(timer2) was not invoked when the time intervals are different.
You should better try to explain what your works means.

As far as I tried, it seems autoconnect() cannot handle multiple timers properly.

Please try something like this:
Code Block
struct ContentView: View {
@State var isPlaying: Bool = true
@State var timeRemaining: Int = 1800
@State var count = 1
@State var count2 = 10
let timer2 = Timer.publish(every: 1, on: .main, in: .default)
let timer = Timer.publish(every: 0.5, on: .main, in: .default)
init() {
_ = timer.connect()
_ = timer2.connect()
}
var body: some View {
VStack {
Text("\(count) \(count2)")
.padding()
}
.onReceive(timer2) { _ in
print("timer2")
if self.timeRemaining > 0 && isPlaying == true {
self.count2 += 1
}
}
.onReceive(timer) { _ in
print("timer")
if self.timeRemaining > 0 && isPlaying == true {
self.count += 1
}
}
}
}


  • Thanks @OOPer, it's been a while, I tried your code but that doesn't work for me either.

    I'm trying Xcode 14.0 beta and it still doesn't work properly, the second timer only works when the value is less than one and any other value only gives a 1 or 0.5 output. VERY strange behaviour

Add a Comment