如何使用 RxSwift 观察 Bool 属性?

Posted

技术标签:

【中文标题】如何使用 RxSwift 观察 Bool 属性?【英文标题】:How to observe Bool properties with RxSwift? 【发布时间】:2016-05-30 12:28:55 【问题描述】:

我的 VC.swift 中有两个 Bool 属性:

var isRecording = false
var isPlaying = false

在 viewDidLoad() 方法中我有这样的代码:

let observable = Observable.combineLatest(self.rx_observe(Bool.self, "isRecording"), self.rx_observe(Bool.self, "isPlaying"))  (val1, val2) -> Void in
        if(val1 == false && val2 == false)
            self.recordButton.enabled = true
            self.playButton.enabled = true
            self.recordButton.setImage(UIImage(named: "record"), forState: UIControlState.Normal)
            self.playButton.setImage(UIImage(named: "play"), forState: UIControlState.Normal)
         else if(val1 == true && val2 == false)
            self.recordButton.enabled = true
            self.recordButton.setImage(UIImage(named: "stop"), forState: UIControlState.Normal)
            self.playButton.enabled = false
         else if(val1 == false && val2 == true)
            self.recordButton.enabled = false
            self.playButton.enabled = true
            self.playButton.setImage(UIImage(named: "stop"), forState: UIControlState.Normal)
            self.recordButton.setImage(UIImage(named: "record"), forState: UIControlState.Normal)
        
    .observeOn(MainScheduler.instance)
    addSubscription(observable.subscribe())

函数 addSubscription(:_) 将订阅添加到 DisposableBag。 问题是闭包中的代码只工作一次。当属性“isRecording”和“isPlaying”改变时它不起作用。如果我希望在更改这些 bool 属性后执行此代码,我应该怎么做?

【问题讨论】:

当状态改变时更改该属性,我的意思是播放或录制将完成并重新开始。您在 viewdidload 中实现了它,因此它在加载时只调用一次。 【参考方案1】:

不要使用Boolrx_observe。而是使用Subject,例如Variable<Bool>

let isRecording = Variable(false)
let isPlaying = Variable(false)

let observable = Observable.combineLatest(isRecording.asObservable(), isPlaying.asObservable())  (val1, val2) -> Void in
    //...

但是,要回答您关于为什么它不适用于 rx_observe 的问题,这是因为 rx_observe 依赖于符合 KVO 的属性。如果您在属性定义前使用 dynamic 关键字,它会起作用:dynamic var isRecording = false。但是,您确实应该使用Subject,例如Variable。查看RxSwift repo 中处理Subjects 的操场页面。它给出了每种类型的示例。

【讨论】:

非常感谢。有用。但是我使用了这个: let observable = Observable.combineLatest(isRecording.asObservable(), isPlaying.asObservable()) (val1, val2) -> Void in //... 啊,谢谢你的收获。我已经更新了答案。我还解释了为什么它以前不适合你。【参考方案2】:

使用最新的 RxSwift 5.0+,您可以使用 BehaviorRelay

let isLoading = BehaviorRelay<Bool>(value: false)

你可以观察到它的价值如下:

isLoading.asObservable().subscribe  status in
                print(status)
            .disposed(by: disposeBag)

【讨论】:

以上是关于如何使用 RxSwift 观察 Bool 属性?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 RxSwift 中观察对象的属性?

如何读取 RxSwift 属性的值? <驱动程序>布尔

RxSwift:返回一个带有错误的新可观察对象

RxSwift:将实际可观察​​对象传递给另一个视图控制器?

使用 RxSwift 的 UICollectionView 数据绑定 - iOS

RxSwift:如何将 Bool 更改为 ObservableType?