Tokamak icon indicating copy to clipboard operation
Tokamak copied to clipboard

Picker bindings don't work when `id: \.self`

Open MaxDesiatov opened this issue 3 years ago • 3 comments

As reported by our user @rbartolome, the binding in this code doesn't work:

struct PickerTest: View {
  @State private var selection: String = ""
  let items: [String] = ["Item 1",
                         "Item 2",
                         "Item 3",
                         "Item 4"]
  var body: some View {
    VStack {
      Picker("MyPicker:", selection: self.$selection) {
        ForEach(self.items, id: \.self) {
          Text($0)
        }
      }
      Text("You selected: \(self.selection)")
    }
  }
}

I've been able to narrow it down to our Picker implementation assuming that SelectionValue generic parameter is always an integer. The assumption is obviously broken in this case, where it is a string.

MaxDesiatov avatar Oct 06 '20 16:10 MaxDesiatov

@rbartolome I'm sorry, but fixing this will require signifcant changes to our Picker implementation, and I'm working on it right now. I would advise you to use an Int binding to array indices in the meantime, as we do in our PickerDemo. Would that be a suitable workaround for you?

MaxDesiatov avatar Oct 06 '20 16:10 MaxDesiatov

@MaxDesiatov The PickerDemo makes no pre-selection. Try set the selection property to 1. It should show the 2nd element in Picker but it shows the default text "Pick a text style..."

rbartolome avatar Oct 07 '20 05:10 rbartolome

Here's another simple example that doesn't update the value correctly, which doesn't use ForEach at all:

import TokamakDOM

@main
struct TokamakApp: App {
  @State var selection: String = "None"

  var body: some Scene {
    WindowGroup("Tokamak App") {
      VStack {
        Text(selection)
        Picker(selection: $selection, label: Text("Picker")) {
          Text("A")
          Text("B")
          Text("C")
        }
      }
    }
  }
}

fwcd avatar Aug 21 '22 15:08 fwcd