繁体   English   中英

willSet 不会在 SwiftUI 的新 @AppStorage 属性上被调用

[英]willSet not being called on SwiftUI's new @AppStorage property

我正在使用 SwfitUI 的新@AppStorage属性。 但是, willSet属性观察器没有触发。

这是我的UserDefaultscodeResult从异步调用更改:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM