2

The following picker isn't updating $selection. Regardless of what the Picker shows while running the app, selection.rawValue always returns 0.

What is preventing the Picker from updating the State variable selection?

import SwiftUI struct OrderPicker: View { let initialIndex: Int @State private var selection: Index enum Index: Int, CaseIterable, Identifiable { case none = 0, first = 1, second = 2, third = 3 var id: Self { self } } init(initialIndex: Int) { self.initialIndex = initialIndex _selection = State(initialValue: OrderPicker.Index(rawValue: initialIndex) ?? .none) } var body: some View { Form { Picker("Order in list", selection: $selection) { ForEach(Index.allCases) { index in Text(String(describing: index)).tag(index) } } } .frame(height: 116) } func getOrderIndex() -> Int { let index = selection.rawValue return index } } 
5
  • 1
    Your code is behaving as expected and is updating selection. You can verify this by adding .onChange(of: selection) { print($0) } to the end of your Form. However, the presence of getOrderIndex, which is unused in your current code, makes me wonder if you're trying to do something like reach into a child view to see it's state from the parent view or something like that. Commented Mar 18, 2022 at 3:36
  • 1
    You need to get rid of those initialization, no need to them, also need to use @Binding, and also using a style for picker as well. Commented Mar 18, 2022 at 3:41
  • @jnpdx You're correct, I am trying to read from selection in a parent class by exposing it with getOrderIndex. Will getOrderIndex not accurately return selection's rawValue? Commented Mar 18, 2022 at 4:00
  • 1
    You cannot reach into child views that way. Shared state should be stored in a parent view and passed down via Binding if necessary. Commented Mar 18, 2022 at 4:04
  • Got it. Swapping my State for a Binding worked! Commented Mar 18, 2022 at 4:19

1 Answer 1

1

Here is an approach for you:

struct ContentView: View { @State private var selection: PickerType = PickerType.none var body: some View { OrderPicker(selection: $selection) } } struct OrderPicker: View { @Binding var selection: PickerType var body: some View { Form { Picker("Order in list", selection: $selection) { ForEach(PickerType.allCases, id: \.self) { item in Text(item.rawValue) } } .pickerStyle(WheelPickerStyle()) .onChange(of: selection, perform: { newValue in print(newValue.rawValue, newValue.intValue) }) } } } enum PickerType: String, CaseIterable { case none, first, second, third var intValue: Int { switch self { case .none: return 0 case .first: return 1 case .second: return 2 case .third: return 3 } } } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.