ios - SwiftUI:观察@Environment 属性变化
问题描述
我试图使用 SwiftUI@Environment
属性包装器,但我无法让它按预期工作。请帮助我理解我做错了什么。
例如,我有一个每秒产生一次整数的对象:
class IntGenerator: ObservableObject {
@Published var newValue = 0 {
didSet {
print(newValue)
}
}
private var toCanc: AnyCancellable?
init() {
toCanc = Timer.TimerPublisher(interval: 1, runLoop: .main, mode: .default)
.autoconnect()
.map { _ in Int.random(in: 0..<1000) }
.assign(to: \.newValue, on: self)
}
}
该对象按预期工作,因为我可以看到控制台日志上生成的所有整数。现在,假设我们希望这个对象是一个环境对象,可以从整个应用程序和任何人访问。让我们创建相关的环境密钥:
struct IntGeneratorKey: EnvironmentKey {
static let defaultValue = IntGenerator()
}
extension EnvironmentValues {
var intGenerator: IntGenerator {
get {
return self[IntGeneratorKey.self]
}
set {
self[IntGeneratorKey.self] = newValue
}
}
}
现在我可以像这样访问这个对象(例如从视图中):
struct TestView: View {
@Environment(\.intGenerator) var intGenerator: IntGenerator
var body: some View {
Text("\(intGenerator.newValue)")
}
}
不幸的是,尽管newValue
是一个@Published
属性,但我没有收到关于该属性的任何更新,并且Text
总是显示 0。我确定我在这里遗漏了一些东西,这是怎么回事?谢谢。
解决方案
Environment
使您可以访问存储在下面的内容,EnvironmentKey
但不会为其内部生成观察者(即,如果 EnvironmentKey 的值自行更改,您将收到通知,但在您的情况下,它是实例,并且存储在 key 下的引用没有更改)。所以它需要手动观察,你那里有发布者吗,如下所示
@Environment(\.intGenerator) var intGenerator: IntGenerator
@State private var value = 0
var body: some View {
Text("\(value)")
.onReceive(intGenerator.$newValue) { self.value = $0 }
}
并且所有的作品...用 Xcode 11.2 / iOS 13.2 测试
推荐阅读
- javascript - 直接表达到生产中的错误端点,但在开发中完美地工作
- sql - 使用通配符覆盖的条件 JOIN
- c++ - Leetcode 寻找最长单值路径的问题
- android - 如何在 Android 10 上访问 IMEI 号码?
- laravel - 根据laravel中父表的列值在whereHas中添加where条件
- soap - Q一步将 pnr 放入多个 Sabre 队列
- go - Kubernetes 客户端代码生成器:代码能否仅存在于本地而不存在于核心生成器工作的存储库中?
- javascript - axios 不工作?我也试过 npminstall axios
- python - 如何在 32 位 Windows 上安装 Spacy?
- angular - IONIC 4 ion-menu Menu ERROR when opening closes