【问题标题】:How to update SwiftUI view after @AppStorage in a separate struct gets updated更新单独结构中的@AppStorage 后如何更新 SwiftUI 视图
【发布时间】:2020-08-17 09:46:30
【问题描述】:

我有以下课程:

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)
    }
}

我希望在 savedCurrencyUserDefaults 更改之后重新渲染视图。

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

【问题讨论】:

  • @AppStorage 按设计在 View 中工作。
  • @Asperi 他们为什么要这样做?
  • @Frankenstein。出于与@State 相同的原因... 提供一种简化的方式,在 UserDefaults 更改时动态更新视图...因此它们是动态属性包装器。
  • @Asperi 很有趣,在任何地方都没有看到这个。谢谢!
  • 你做了什么来完成这项工作?这正是我想要实现的目标。

标签: swift swiftui combine


【解决方案1】:

更新

正如@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 {
    @ObservedObject var formatter = PriceFormatter(price: 5)
    
    var body: some View {
        Text(formatter.formatted)
    }
}

旧答案。适用于 iOS

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

【讨论】:

猜你喜欢
  • 2020-06-27
  • 1970-01-01
  • 2021-04-26
  • 2021-09-09
  • 1970-01-01
  • 1970-01-01
  • 2019-10-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多