tony
tony

Reputation: 23

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

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
            }
        }
    }
}

can anyone suggest any changes to my code?

Upvotes: 1

Views: 266

Answers (2)

tony
tony

Reputation: 23

This gives me some very unusual results

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

    }
}

despite the intervals being the same, the counters increase at different rates, even randomly

Upvotes: 0

vacawama
vacawama

Reputation: 154593

Move the timers out of the body and define them as properties of the View:

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).autoconnect()
    let timer = Timer.publish(every: 0.5, on: .main, in: .default).autoconnect()
    
    var body: some View {
        
        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
            }
        }
    }
}

Upvotes: 3

Related Questions