如何在更新单独结构中的@AppStorage 后更新 SwiftUI 视图

How to update SwiftUI view after @AppStorage in a separate struct gets updated

我有一个关注class:

struct PriceFormatter {
    @AppStorage(UserDefaultsKey.savedCurrency)
    var savedCurrency: String?

    let price: Float
    
    init(price: Float) {
        self.price = price
    }
    
    var formatted: String {
        return "\(savedCurrency) \(price)"
    }
}

以及以下视图:

struct PriceText: View {
    let price: Float
    
    var body: some View {
        Text(PriceFormatter(price: self.price).formatted)
    }
}

我希望视图在 UserDefaultssavedCurrency 更改后重新呈现。

@AppStorage 是视图的一部分时,我让它工作起来很容易,但我不确定在这种情况下该怎么做。我尝试将 @ObservableObject@Published 一起使用,或者尝试制作一个 Combine Publisher 并订阅它,但也没有成功。

更新

正如@Klaas 所指出的,从 iOS 14.5 开始,可以在 ObservableObject (https://developer.apple.com/documentation/ios-ipados-release-notes/ios-ipados-14_5-release-notes)

中使用 @AppStorage

工作解决方案现在看起来像这样:

class PriceFormatter: ObservableObject {
    @AppStorage(UserDefaultsKey.savedCurrency)
    var savedCurrency: String?

    let price: Float
    
    init(price: Float) {
        self.price = price
    }
    
    var formatted: String {
        return "\(savedCurrency) \(price)"
    }
}

并像这样使用:

struct PriceText: View {
    @StateObject var formatter = PriceFormatter(price: 5)
    
    var body: some View {
        Text(formatter.formatted)
    }
}

旧答案。适用于 iOS < 14.5

正如@Asperi 所指出的,@AppStorage 应该只在 View 中使用。隐含地也写在这里:https://developer.apple.com/documentation/swiftui/appstorage