5

I am tearing out my hair trying to figure out how to bind the picked value in my SwiftUI view:

The picker needs to be bound to the Int returned from the tags. I need to covert this Int to the String and set the Binding. How?

struct ContentView: View { @Binding var operatorValueString:String var body: some View { Picker(selection: queryType, label: Text("Query Type")) { ForEach(0..<DM.si.operators.count) { index in Text(DM.si.operators[index]).tag(index) } }.pickerStyle(SegmentedPickerStyle()) } } 

How and where can I set my operatorValueString ?

operatorValueString = DM.si.operators[queryType] //won't compile.

2
  • Have you defined queryType somewhere, Picker is expecting a binding. BTW DM.si.operators.indices is easier to use than count. I don't like the segmented picker. I had to use a ObservedObject with a PassthroughSubject publisher as well to get it to work the way I wanted. Commented Aug 28, 2019 at 17:41
  • Got a sample to share? This is driving me mad. Commented Oct 29, 2019 at 11:34

1 Answer 1

12

You can achieve the result, using your own custom binding that sets the string, whenever the picker's selection changes:

struct ContentView: View { @State private var operatorString = "" var body: some View { VStack { Subview(operatorValueString: $operatorString) Text("Selected: \(operatorString)") } } } struct Subview: View { @Binding var operatorValueString: String @State private var queryType: Int = 0 let operators = ["OR", "AND", "NOT"] var body: some View { let binding = Binding<Int>( get: { self.queryType }, set: { self.queryType = $0 self.operatorValueString = self.operators[self.queryType] }) return Picker(selection: binding, label: Text("Query Type")) { ForEach(operators.indices) { index in Text(self.operators[index]).tag(index) } }.pickerStyle(SegmentedPickerStyle()) } } 
Sign up to request clarification or add additional context in comments.

6 Comments

That is what I wound up doing. Seems like Picker should have another binding.
Unfortunately this led to a infinite loop when you come back and edit. How do you set the Binding to reflect the existing selection?
@jimijon I don't follow. What is the code that leads to an infinite loop?
I need to send overt in the binding the operatorValueString... then I need to set the binding to the proper number of the picker. However, that means I need to set self.querytype in the init, which then causes the loop. I must be missing something very obvious
Amazing! I spent a whole day trying to do something like that using Combine, but that would just make @Binding cause an infinite loop by constantly recalculating body. For some reasons SwiftUI feels extremely hacky beyond the simplest of things.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.