ios - UIView 作为@EnvironmentObject 的订阅者

标签 ios swift swiftui publish-subscribe combine

我有一个在工作线程中更新的@EnvironmentObject,并且几个 SwiftUI View 订阅了对已发布值的更改。

这一切都很好。

但我正在努力让 UIView 订阅@EnvironmentObject 中的更改。

给定

@EnvironmentObject var settings: Settings 

where Settings is:

final class Settings {
    @Published var bar: Int = 0
    @Published var beat: Int = 1
    etc.
}

SwiftUI View 根据发布的值变化进行更新。

但是现在,我想声明一个接收器,该接收器在符合 UIViewRepresentable 的 UIView 中接收发布的值。

我一直在研究 Combine 这本书,并认为我可以用类似的东西声明一个 .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 方法中使用一些东西,但没有成功。

我显然犯了一些相当简单和根本性的错误,我肯定会很感激你朝正确的方向前进,因为我正试图弄清楚这个问题!

谢谢!

最佳答案

您必须存储对从 .sink 收到的 AnyCancellable 的引用:

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 时自动取消订阅。

关于ios - UIView 作为@EnvironmentObject 的订阅者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62585953/

相关文章:

ios - 如何制作兼容的密码扩展?

swift - Firebase : Read-only & non-realtime mode activated, 如何在控制台上添加子节点

ios - CAGradientLayer 没有得到形状

ios - 多次使用 Text 时,SwiftUI 上没有更多上下文,表达式类型不明确,如何解决?

swift - 在 SwiftUI 路径点添加实心圆圈(标记)

ios - 如何自定义 Google Maps for iOS Swift 的 "myLocationButton"

ios - 以编程方式创建自定义 UITableViewCell - Objective C

ios - 使用 UITableView 单元格作为 UIView 并通过点击它来永久更改它的颜色(颜色源来自生成随机颜色的函数)

ios - UITableView:如何调整包含自动换行标签的标题大小

ios - 如何防止重绘整个无限滚动列表?