Because the selection is Customer?
but the tag is Customer
. Those are two different types.
Perhaps the easiest way to solve this is like below. ForEach
will automatically assign a tag
of whatever type is used for its id
parameter, which in my example I have made a UUID
.
First, make sure our Customer
type is Identifiable
, which it already is since you have an id
property; you just need to let the compiler know.
struct Customer: Identifiable {
let id = UUID()
//...blah blah blah
}
Then, in your View
:
struct CustomerPickerView: View {
//sample data
let customers: [Customer] = [
Customer(given_name: "Charlotte", family_name: "Grote"),
Customer(given_name: "Shauna", family_name: "Wickle"),
Customer(given_name: "Mildred", family_name: "Haversham"),
]
//make the selection property the same type as your Customer.id property
@State private var customerID = UUID()
//we set it to a dummy value initially;
//the chances of an accidental collision are miniscule
//if you want it to be set to, say, the first value in customers, do this instead:
//@State private var customerID: UUID
//
//init() {
// _customerID = State(initialValue: customers[0].id)
//}
var body: some View {
Picker("Choose a client", selection: $customerID) {
//you don't need self.customers unless you are supporting older code (<iOS14, IIRC)
//and you don't need to give ForEach an explicit id -
// since Customer has an id property, it will automatically use that
//and you also don't need to explicitly type the parameter to the closure
ForEach(customers) { customer in
Text("\(customer.given_name!) \(customer.family_name!)")
//ForEach will automatically assign a tag of the same type as Customer.id
// which is the same type as customerID which we use for the selection
}
.onChange(of: customerID) { print($0) } //so we can watch what's going on
}
}
}
It's possible to use a Customer
value directly as the selection; you just have to explicitly assign a tag
of the correct type.