I've created a UserDefaults extension to generate custom bindings.
extension UserDefaults {
func boolBinding(for defaultsKey: String) -> Binding<Bool> {
return Binding (
get: { return self.bool(forKey: defaultsKey) },
set: { newValue in
self.setValue(newValue, forKey: defaultsKey)
})
}
func cardPileBinding(for defaultsKey: String) -> Binding<CardPile> {
return Binding (
get: { let rawValue = self.object(forKey: defaultsKey) as? String ?? ""
return CardPile(rawValue: rawValue) ?? .allRandom
},
set: { newValue in
self.setValue(newValue.rawValue, forKey: defaultsKey)
})
}
}
For the sake of completeness, here is my enum
enum CardPile: String, CaseIterable {
case allRandom
case numbers
case numbersRandom
case daysMonths
case daysMonthsRandom
}
I've also created UI elements that use these bindings:
var body: some View {
VStack {
Toggle("Enable", isOn: UserDefaults.standard.boolBinding(for: "enable"))
Picker("Card Pile", selection: UserDefaults.standard.cardPileBinding(for: "cardPile")) {
ForEach(CardPile.allCases,
id: \.self) {
Text("\($0.rawValue)")
.tag($0.rawValue)
}
}
}
}
When I tap the toggle, it updates correctly. However when I tap the picker and select a different value, the binding setter gets called, but the view does not refreshed to reflect the change in value. (If I force quit the app and re-run it, the I see the change.) I would like to find out why the Binding<Bool> works as I'd expected (ie updates the UI when the value changes) but the Binding<CardPile> behaves differently. any/all guidance very much appreciated. Note: I get the same behavior when the enum use Int as its rawValue