[英]willSet not being called on SwiftUI's new @AppStorage property
I am utilising SwfitUI's new @AppStorage
property.我正在使用 SwfitUI 的新@AppStorage
属性。 However, the willSet
property observer is not firing.但是, willSet
属性观察器没有触发。
Here is my UserDefaults
value codeResult
changing from an asynchronous call:这是我的UserDefaults
值codeResult
从异步调用更改:
class Main: ObservableObject {
func code(data: [AnyHashable:Any?]){
UserDefaults.standard.set("incorrect", forKey: "codeResult")
}
}
And below in my View, willSet is not being called:在我的视图下面, willSet 没有被调用:
struct MainView: View {
@ObservedObject var main = Main()
@ObservedObject var mainCountdown: CountDown
@ObservedObject var locationManager = LocationManager()
@State private var keyboardHeight: CGFloat = 0
@State var showCode: Bool = false
@AppStorage("codeResult") var codeResult = UserDefaults.standard.string(forKey: "codeResult") ?? "" {
willSet {
print("willSet: \(newValue)") // doesn't fire
}
didSet {
print("didSet: \(oldValue)") // doesn't fire
}
}
Any idea why it's not firing?知道为什么它不发射吗?
The willSet/didSet are observers for property change (not publisher observers). willSet/didSet 是属性更改的观察者(不是发布者观察者)。 Thus to get into willSet/didSet you have to change property codeResult
directly.因此,要进入 willSet/didSet,您必须直接更改属性codeResult
。
Here is a demo that depicts differences - both buttons update Text (because codeResult
is dynamic observable property, but only direct assign to codeResult
activates property willSet/didSet)这是一个描述差异的演示 - 两个按钮都更新文本(因为codeResult
是动态可观察属性,但只能直接分配给codeResult
激活属性 willSet/didSet)
Tested with Xcode 12b3 / iOS 14.使用 Xcode 12b3 / iOS 14 进行测试。
struct DemoAppStorageDidSet: View {
@AppStorage("codeResult") var codeResult: String = "Default" { // << default value
willSet {
print("willSet: \(newValue)")
}
didSet {
print("didSet: \(oldValue)")
}
}
var body: some View {
VStack {
Text("Code Result: \(codeResult)")
Divider()
Button("AppStore Update") {
self.codeResult = "AppStore" // << activates willSet/didSet !!
}
Divider()
Button("UserDefaults Update") {
UserDefaults.standard.set("UserDefaults", forKey: "codeResult")
}
}
}
}
Note: you don't need to initialise AppStorage
with UserDefaults value, it is read by default.注意:您不需要使用 UserDefaults 值初始化AppStorage
,它是默认读取的。
Adding onReceive()
to the view seemed to successfully track changes to codeResult
where I could execute code blocks:将onReceive()
添加到视图似乎成功地跟踪了对codeResult
的更改,我可以在其中执行代码块:
.onReceive(self.codeResult.publisher.collect()) {_ in
if self.codeResult == CodeResult.incorrect.rawValue {
print("CHANGED TO INCORRECT")
self.showCode = false
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.