Hey is it normal for some SwiftUI code to get called multiple times as a result of a state change or save operation? This code is a picker with a choice of 4 options. The selected option is then saved to UserDefaults by the method saveBase. I put a print statement in the method to confirm my value was arriving correctly and discovered that the method is getting called 19 times every time a change is made to the picker. The code is working fine saving and restoring baseCurr. As a Firmware Engineer with experience in assembly and C I would think this is pretty buggy code, but I'm not so sure. Any ideas?
class UserData: ObservableObject {
@Published var baseCurr: Int = 0
func saveBase() -> () {
let defaults = UserDefaults.standard
defaults.set(self.baseCurr, forKey: "base")
print(" base Curr = \(self.baseCurr)")
}
}
struct aboutView: View {
@EnvironmentObject var userData: UserData
let baseCurrs = ["block A", "block B","block C","block D"]
var body: some View {
Form {
VStack (alignment: .leading) {
Text("Select Base")
Picker(selection: $userData.baseCurr, label: Text("Curr >")) {
ForEach(0 ..< baseCurrs.count) {
Text( baseCurrs[$0])
}
.onChange(of: userData.baseCurr) { newValue in
userData.saveBase()
}
}
}
.padding()
}
.navigationBarTitle("About", displayMode: .inline)
}
}
As NewDev pointed out in the comments, you need to attach the
onChange
modifier to a single View (likePicker
orVStack
) instead ofForEach
.However, you can make your code a little bit cleaner by completely removing both the
.onChange
modifier and thesaveBase()
function.You can add
didSet
to thebaseCurr
property to save the value whenever it's set:Now you don't need
onChange
: