I have a custom preferences class and I would like to trigger a function whenever that is changed, at the moment it doesn't seem to work for some reason.
Here is the class
class Preferences: ObservableObject, Equatable{
static func == (lhs: Preferences, rhs: Preferences) -> Bool {
return lhs.email == rhs.email && lhs.password == rhs.password && lhs.faceID == rhs.faceID && lhs.currency == rhs.currency && lhs.colourScheme == rhs.colourScheme && lhs.appTheme == rhs.appTheme
}
@Published var email: String = ""
@Published var password: String = ""
@Published var faceID: Bool = false
@Published var currency: Currencies = .EUR
@Published var colourScheme: ColourScheme = .system
@Published var appTheme: Theme = .orange
This is stored in a viewmodel
class ViewModel: ObservableObject {
@Published var preferences = Preferences()
}
And here is the onchange call
.onChange(of: viewModel.preferences){ newValue in
viewModel.updateSettings(faceID: viewModel.preferences.faceID, currency: viewModel.preferences.currency, colourScheme: viewModel.preferences.colourScheme, appTheme: viewModel.preferences.appTheme)
}
The onchange never gets called? Any help would be appreciated. Thanks
CodePudding user response:
Because preferences is an object there is no change, i.e. it is always the same object. SwiftUI is designed to work with value semantics, i.e. structs, so try making Preferences
a struct instead.
Also there is no need for that view model object, in SwiftUI the View struct is a view model already, which SwiftUI uses to create/update/remove UIView objects on screen. We use @StateObject
when we need a reference type in @State
, e.g. when doing something async, however the new .task
replaces that need.