UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Picker not updating selection binding for Realm entities

Forums > SwiftUI

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?

2      

BUILD THE ULTIMATE PORTFOLIO APP Most Swift tutorials help you solve one specific problem, but in my Ultimate Portfolio App series I show you how to get all the best practices into a single app: architecture, testing, performance, accessibility, localization, project organization, and so much more, all while building a SwiftUI app that works on iOS, macOS and watchOS.

Get it on Hacking with Swift+

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.