[英]willSet not being called on SwiftUI's new @AppStorage property
我正在使用 SwfitUI 的新@AppStorage
属性。 但是, willSet
属性观察器没有触发。
这是我的UserDefaults
值codeResult
从异步调用更改:
class Main: ObservableObject {
func code(data: [AnyHashable:Any?]){
UserDefaults.standard.set("incorrect", forKey: "codeResult")
}
}
在我的视图下面, 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
}
}
知道为什么它不发射吗?
willSet/didSet 是属性更改的观察者(不是发布者观察者)。 因此,要进入 willSet/didSet,您必须直接更改属性codeResult
。
这是一个描述差异的演示 - 两个按钮都更新文本(因为codeResult
是动态可观察属性,但只能直接分配给codeResult
激活属性 willSet/didSet)
使用 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")
}
}
}
}
注意:您不需要使用 UserDefaults 值初始化AppStorage
,它是默认读取的。
将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.