1

I'm trying to create a counter in order to randomize a number every each second.

As far, I get this code, but it activates automatically. It would be a pleasure to know how to activate this timer with a button.

My code:

struct BSR: View {
    @State private var NumBSR = "---"

    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()

    var body: some View {
        ZStack {
            Image("BSR")
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(width: 62, height: 61, alignment: .center)

            Text(String(NumBSR))
                .font(.body)
                .foregroundColor(.white)
                .frame(width: 50, height: 40, alignment: .bottom)

        }.onReceive(timer, perform: { time in
            let Num = Int.random(in: 0...5)
            NumBSR = String(Num)
        })
    }
}

Sorry if I can't write the code property, Im still learning. Thanks for your help.

pawello2222
  • 46,897
  • 22
  • 145
  • 209

1 Answers1

2

You can try the following:

struct BSR: View {
    @State private var NumBSR = "---"
    @State private var timer: AnyCancellable? // declare as `@State`, assign later

    var body: some View {
        ZStack {
            Image("BSR")
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(width: 62, height: 61, alignment: .center)
            VStack {
                Text(String(NumBSR))
                    .font(.body)
                    .foregroundColor(.white)
                    .frame(width: 50, height: 40, alignment: .bottom)
                Button(action: startTimer) { // create timer on button tap
                    Text("Start timer")
                }
            }
        }
    }

    func startTimer() {
        // create on demand, not when the the view is initialised
        timer = Timer.publish(every: 1.0, on: .main, in: .common)
            .autoconnect()
            .sink { _ in
                let Num = Int.random(in: 0...5)
                NumBSR = String(Num)
            }
    }
}

You can also move the timer logic to a view model like in:

pawello2222
  • 46,897
  • 22
  • 145
  • 209