I have a view that passes a binding to another view which includes a Picker
. When an item is selected in the picker, the binding is not updated.
Here is the parent view:
struct AccountsView: View {
@SceneStorage("selectedAccount") private var selectedAccount: String?
@SceneStorage("isAddingAccount") private var isAddingAccount: Bool = false
var body: some View {
VStack {
AccountsToolbar(selection: selectedAccountId, isAddingAccount: $isAddingAccount)
if isAddingAccount {
CreateAccountView(isAddingAccount: $isAddingAccount)
}
}
.frame(maxHeight: .infinity, alignment: .topLeading)
}
var selectedAccountId: Binding<ObjectId?> {
Binding(
get: { selectedAccount == nil ? nil : try? ObjectId(string: selectedAccount!) },
set: { print("new id: \($0)"); selectedAccount = String(describing: $0) }
)
}
}
...and the child view:
struct AccountsToolbar: View {
@Binding var selection: ObjectId?
@Binding var isAddingAccount: Bool
@ObservedResults(Account.self) var accounts
var body: some View {
HStack {
Picker("Account", selection: $selection) {
ForEach(accounts, id: \.self) { account in
Text(account.name).tag(account._id)
}
}
Button {
isAddingAccount = true
}
label: {
Image(systemName: "plus.circle.fill")
.resizable()
.foregroundStyle(.white, .indigo)
.symbolRenderingMode(.palette)
.frame(width: 20, height: 20)
}
.buttonStyle(.borderless)
}
.frame(height: 64)
}
}
The Realm model looks like this:
class Account: Object, ObjectKeyIdentifiable {
@Persisted(primaryKey: true) var _id: ObjectId
@Persisted var name: String
@Persisted var apiKey: String
@Persisted var privateKey: String
}
As I say, when an item is chosen from the Picker
, the binding is not updated. The print
in the set:
of the binding in the AccountsView
prints nil
.
I have tried:
- conforming the model to the
Identifiable
protocol
- using a
String?
binding, rather than an ObjectId?
binding
- using
Text(...).id(...)
rather than Text(...).tag(...)
- eliding the
\.self
in the ForEach
What might I be missing/doing wrong?