NRGX
NRGX

Reputation: 19

Storing value from a picker and passing it into a function

I am trying to get a value from a picker and store it so it can be passed into the function...

The problem is that I try to pass the Picker value into a function as the action for a button, then covert it to an integer, but it just uses the default value, and it seems like the it is never reading the value from the picker

Here is my ContentView file for reference:

struct ContentView: View {
    
    @State var repetitions: String
    
    let directions : [String] = ["Left", "Right"]
    
    var body: some View {
        VStack {
            Picker("Values", selection: $repetitions) {
                ForEach((0...100), id: \.self) {
                        Text("\($0)")
                }
            }
            Button(action: {choseDirection(reps: repetitions)}, label: { // value passed into function here
                Text("Start Drill")
                    .frame(minWidth: 0, maxWidth: 200)
                    .padding()
                    .foregroundColor(.white)
                    .background(
                        RoundedRectangle(cornerRadius: 10)
                            .stroke(lineWidth: 2)
                            .background(Color.blue.cornerRadius(10))
                    )
            })
            
        }
        
    }
    func choseDirection(reps: String) {
        let reps = Int(reps) ?? 1 // HERE always uses default value instead of value from picker
        var count = 1
        while count <= reps {
            
            // does some action
        }
    }
    
    
    
}

So how can I change this to read the value, so it can be used in the function for the correct amount of repetitions

Upvotes: 1

Views: 150

Answers (1)

aheze
aheze

Reputation: 30326

Inside the Picker, you're looping over 0...100. The ForEach automatically assigns a tag to each Int. The picker then uses the tag to keep track of the selection inside repetitions.

However, because repetitions is a String, it doesn't match with each selection (0...100)'s type (Int). As a result, repetitions never gets set. To fix, also make repetitions an Int.

struct ContentView: View {
    
    @State var repetitions = 0 /// Int, not String
    
    let directions: [String] = ["Left", "Right"]
    
    var body: some View {
        VStack {
            Picker("Values", selection: $repetitions) {
                ForEach((0...100), id: \.self) {
                        Text("\($0)")
                }
            }
            Button(action: {
                choseDirection(reps: repetitions)  // value passed into function here
            }) {
                Text("Start Drill")
                    .frame(minWidth: 0, maxWidth: 200)
                    .padding()
                    .foregroundColor(.white)
                    .background(
                        RoundedRectangle(cornerRadius: 10)
                            .stroke(lineWidth: 2)
                            .background(Color.blue.cornerRadius(10))
                    )
            }
        }
    }
    func choseDirection(reps: Int) {
        print("reps: \(reps)")
        var count = 1
        
        /// comment out for now, otherwise it's an infinite loop
//        while count <= reps {
            // does some action
//        }
    }
}

Upvotes: 1

Related Questions