Need to use Picker item as a value in a calculation

So, I've looked everywhere and battled with this for days with no luck. I've tried four of five different approaches with none of them working for me.

In JavaScript I have no issue resolving my problem and I'm confident it's as simple but I'm just not that used to Swift as a language yet. How I've solved this in JavaScript before is to pick a value from the list by targeting it with .value so I wasn't sure if there was a similar option here.

I have a WheelPicker in use to select a scale value by which the calculation needs to be multiplied. In order to conform to the requirements of the picker, this is an array of strings.

I have a for loop that correctly iterates the array and populates. I also have a calculation that works with it, however, the calculation is multiplying by the 'index' of the array rather than the value itself. So for example, if the picker is on the default value, the entire calculation is multiplied by 0, and so on.

I thought that by converting the String into a Double (I need decimal places) it'd resolve the issue, but the calculation still works via the index position.

Any help would be greatly appreciated! You guys helped me solve another issue so I'm hopeful.

Snippets below.

Array
Code Block
@State private var scales = ["1.000", "1.067", "1.125", "1.200", "1.250", "1.333", "1.414", "1.500", "1.618"]

Variable to make the picker work
Code Block
@State private var scaleSelector = 0

Calculation that takes in values and multiples by the scale (calculation works as expected without the Scale anyway)
Code Block
func pxToEms(pixelInt: Double, baseInt: Double, scales: Double) -> Double {
  let emValue: Double = (pixelInt / baseInt) * scales
            return emValue
}

Wheel picker for loop (just in case)
Code Block
Picker(selection: $scaleSelector, label: Text("Scale")) {
ForEach(0 ..< scales.count) {
   Text(self.scales[$0]).tag($0)
}
}
.pickerStyle(WheelPickerStyle())

Where it renders in the UI
Code Block
Text("\(pixelText) Pixels is \(String(format: "%.3f", pxToEms(pixelInt: Double(pixelText) ?? 0, baseInt: Double(baseText) ?? 16, scales: Double(scaleSelector)))) Em")

Answered by Claude31 in 612769022
Change
Code Block
Text("Result: \(pxToEms(pixelInt: 2, baseInt: 3, scales: Double(scaleSelector)))")


with
Code Block
        Text("Result: \(pxToEms(pixelInt: 2, baseInt: 3, scales: Double(scales[scaleSelector])))")


Because
Double(scaleSelector))
is 0, 1, 2 (the row selected) and not the scale.
The UI on this is completely terrible but hopefully it illustrates how to use a Picker to select the appropriate "scales" value for your calculations.

Cheers,
  • Dan

Code Block
struct ContentView: View {
@State private var scaleSelector = 0
let scales = [1.000, 1.067, 1.125, 1.200, 1.250, 1.333, 1.414, 1.500, 1.618]
  var body: some View {
VStack {
Picker(selection: $scaleSelector, label: Text("Scales")) {
ForEach(0..<scales.count) {
Text("Scale by: \(self.scales[$0])")
}
}.labelsHidden()
Text("Result: \(pxToEms(pixelInt: 2, baseInt: 3, scales: Double(scaleSelector)))")
}
}
func pxToEms(pixelInt: Double, baseInt: Double, scales: Double) -> Double {
let emValue: Double = (pixelInt / baseInt) * scales
return emValue
}
}


Thanks so much for this. Sadly this appears to not calculate as I'd expect either.

Also, I appreciate the lack of previous context. This calculation allows the user to set a baseline pixel value (say 16px for browser default) and an object pixel value (say again, 16px) and see the relative em value. So, baseValue/pxValue = emValue.

In the case of this calculation, 16px/16px = 1em.

If I then want to multiply that by a particular scale to get the difference in result depending on my conversion scale of choice, I want to see the difference this causes. The default, in this case, is 1.000. So the result should be (16/16) * 1.000 = 1.

For me, running this code, I get an initial result of 0.000.

If I then push up the wheel, I see a pattern of 0.000, 0.666, 1.333, 2.000, 2.666, 3.333 and so on. Any thoughts/did you see different results?
I've just realised you can't edit posted replies, so to correct my previous response, the calculation is:

pxValue/baseValue * scale. Not base/px as I said.

For further examples, 16px/32px * 1.000 = 0.5em or, if using the Golden Ratio; 16px/32px * 1.618 = 0.809em
Accepted Answer
Change
Code Block
Text("Result: \(pxToEms(pixelInt: 2, baseInt: 3, scales: Double(scaleSelector)))")


with
Code Block
        Text("Result: \(pxToEms(pixelInt: 2, baseInt: 3, scales: Double(scales[scaleSelector])))")


Because
Double(scaleSelector))
is 0, 1, 2 (the row selected) and not the scale.
You absolute hero! Between you guys, you've resolved days of headache for me. Thanks so much!
Need to use Picker item as a value in a calculation
 
 
Q