我有一个@EnvironmentObject,它在工作线程中进行了更新,并且几个SwiftUI视图订阅了对已发布值的更改。
这一切都很好。
但是我正在努力让UIView订阅@EnvironmentObject中的更改。
给予
@EnvironmentObject var settings: Settings
where Settings is:
final class Settings {
@Published var bar: Int = 0
@Published var beat: Int = 1
etc.
}
SwiftUI视图可以很好地根据发布的值更改进行更新。
但是现在,我想声明一个接收器,该接收器在符合UIViewRepresentable的UIView中接收发布的值。
我一直在研究“合并”书,并认为我可以使用以下内容声明一个.sink闭包:
func subscribeToBeatChanges() {
settings.$bar
.sink(receiveValue: {
bar in
self.bar = bar
print("Bar = \(bar)")
} )
settings.$beat
.sink(receiveValue: {
beat in
self.beat = beat
print("Beat = \(beat)")
self.setNeedsDisplay()
} )
}
不幸的是,当调用subscribeToBeatChanges()时,闭包仅被调用一次。我想要的是每次@EnvironmentObject值中的@Published属性更改时都调用闭包。
我也尝试在UIViewRepresentable包装器中进行预订,并在makeUIView方法中进行了某些操作,但未成功。
我显然在做一些相当简单而根本的错误,并且肯定会朝正确的方向前进,因为我会cross目结舌地试图解决这个问题!
谢谢!
答案 0 :(得分:0)
您必须存储对从AnyCancellable
返回的.sink
的引用:
private var cancellables = Set<AnyCancellable>()
func subscribeToBeatChanges() {
settings.$bar
.sink(receiveValue: {
bar in
self.bar = bar
print("Bar = \(bar)")
} )
.store(in: &cancellables) // <-- store the instance
settings.$beat
.sink(receiveValue: {
beat in
self.beat = beat
print("Beat = \(beat)")
self.setNeedsDisplay()
} )
.store(in: &cancellables) // <-- store the instance
}
如果您不存储它,则AnyCancellable
实例将自动取消对deinit的订阅。