How to use a picker to get some value after a selection is made?

415 views Asked by At

I have a picker that that reads in from a list of tuples and have a couple questions on how to make it work. What I want to do is that the picker displays some strings and when the user makes a selection a value corresponding to the string is saved into a variable. Then I want to use this variable in a function to calculate something a print the calculation to the user. I currently have:

@State private var rating: Int = 0

func scale(rating: Float, someValue1: Float, someValue2: Float) -> Float{
    return (rating + someValue1 * 2.5 + someValue2 * 1.5) / 10
}

var arrayOfTuples: [(score: String, value: Int)] = [
        (score: "A+", value: 60),
        (score: "A", value: 55),
        (score: "A-", value: 50),
        (score: "B+", value: 45),
        (score: "B", value: 40),
        (score: "B-", value: 35),
        (score: "C+", value: 30),
        (score: "C", value: 25),
        (score: "C-", value: 20),
        (score: "D+", value: 15),
        (score: "D", value: 10),
        (score: "D-", value: 5),
        (score: "F", value: 0)
    ]

Picker(selection: $rating, label: Text("Choose")) {
                        ForEach(0 ..< arrayOfTuples.count) {
                            Text(self.arrayOfTuples[$0].score)
                        }
                    }

This code only is displaying the score part of the arrayOfTuples (A+, A, A-, etc.) which is what I want but when the user selects something from the picker I don't think it's saving the value of the corresponding score into the variable "rating". I then want to use rating to calculate the function when a button is pressed:

Button(action: {
            print(self.scale(rating: Float(self.rating), someValue1: Float(self.someValue1) ?? 0, someValue2: Float(self.someValue2)))
        }) {
            Text("Calculate")
        }

Also, all of this is done inside the ContentView struct created when an app is created in Xcode so I don't know if I am declaring and defining the functions where they're supposed to be so if there is a better way please let me know.

Additionally, the picker is the default picker. I would prefer to use the wheel picker however when I use it it shows it in the main screen where I would prefer it comes up as a pop-up only when the user presses the selection button.

Finally, as you can see in the button the action is printing the value. However, I don't want to print the value rather display it to the user through a popup box or somewhere else that the user can see.

Any ideas how to do this? Thank you so much in advance.

1

There are 1 answers

2
SuperTully On

There's quite a bit you need to do to accomplish everything you're asking, but let's start with the picker view basics. You need to conform to the Picker View Data Source and Delegate protocols, then implement the required methods the picker view expects. Here's an example:

class PickerViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
    
//...rating and tuple variables

overide func viewDidLoad() {
   let pickerView = UIPickerView()
   pickerView.dataSource = self
   pickerView.delegate = self
   self.view.addSubview(pickerView)
}

func numberOfComponents(in pickerView: UIPickerView) -> Int {
    return 1
}

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    return arrayOfTuples.count
}

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    return arrayOfTuples[row].score
}

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    rating = arrayOfTuples[row].value
}

}

They key to storing the picker's value in the rating variable is the didSelectRow method. The code example I wrote just takes a plain picker view and adds it onto the view controller's view, without thought to placement or constraints or anything, so it's not going to be pretty, but it illustrates how to use a picker view for selecting data. If you want to have the picker view pop-up and hide, there's several ways to do it, including adding the subview over the top of other views, and the removing it from its super view, or presenting a new view controller. How familiar are you with doing that in Swift?