1

I am trying to make the animation progress to a certain number value. I get errors, I can't figure out what the reason is. SwiftUi IOS15

What are the parameters - Number: 600; Total: 1000

I am trying to run a progress animation to the number 600 out of 1000

let number: String
let total: Int
let timer = Timer.publish(every: 0.1, on: .main, in: .common).autoconnect()

ProgressView(name, value: Double(number), total: Double(total))
  .onReceive(timer) { _ in
      if number < Double(total) {
         Double(number) += Double.random(in: 0...4)
         }
     }

UPD: This is part of the code that I didn't add initially

struct Params: Identifiable {
    let id = UUID()
    let num: String
}

extension Params {
    static func getAll() -> [Params] {
        return [
            Params(num: "650"),
            Params(num: "80"),
            Params(num: "900")
        ]
    }
}

2 Answers 2

3

Your number property is a String, while Double(total) is a Double. You cannot compare a String and a Double with the < operator.

Your number property and your total property should both be declared Double, so you don't have to constantly convert them from String to Double.

Also, you cannot assign to a function call like Double(number), so Double(number) += ... cannot work.

Also, you cannot assign to a property declared with let like let number: String.

Also, if you want to modify a property in an onReceive body, the property needs to be wrapped with @State or @Binding.

import SwiftUI

struct DemoView: View {
    var name: String
    var max: Double
    var total: Double
    @State var number: Double = 0
    
    var body: some View {
        VStack {
            ProgressView(name, value: number, total: total)
                .onReceive(
                    Timer.publish(
                        every: 0.1,
                        on: .main,
                        in: .common
                    ).autoconnect()
                ) { _ in
                    if number < max {
                        number += Double.random(in: 0...4)
                    }
                }
            
            Button("Reset") { number = 0 }
        }
    }
}

import PlaygroundSupport
PlaygroundPage.current.setLiveView(
    DemoView(
        name: "Test",
        max: 600,
        total: 1000
    ).padding()
)
Sign up to request clarification or add additional context in comments.

4 Comments

I have updated my code, I get data from the struct Params: Identifiable structure, then I display them via ForEach, please take a look
I don't understand why that makes a difference. Convert the Strings to Doubles once when you initialize the view that wraps the ProgressView.
Then how do I pass the String value to max:
I can use it like this max: Double(num)! The num value is a String from the struct Params: Identifiable structure ?
0

Could you provide full code for the file? On the screenshot there are multiple mistakes:

  1. You cannot compare number and Double(total), because they are of different types. If you want to compare some number inside a String, firstly convert your string to a number, for example: let intFromString = Int(number), then you will be able to compare like this: if intFromString < total { ... }
  2. You cannot add Double to your String. You can add Double to another Double, and if this happens inside some View, you should use @State properties, for example:
  • @State var number: Double = 0
  • @State var total: Int = 0

And later: number += Double.random...

2 Comments

Thanks for the answer, I know that your option works, but it doesn't suit me, because I pass parameters to progressView from another structure
I added the code, it shows where I get the data from

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.