實現(xiàn)一個需求 —— 使用 RxSwift 訂閱 UIView 的 isHidden 屬性

最近在做項目的時候,遇到了一個需求。我有三個 View(View1, View2, View3),View1 和 View2 其中一個顯示,View3 就顯示。

稍微思考了一下,覺得訂閱 isHidden 屬性的改變,然后通過 CombineLatest 組合 Observable 來實現(xiàn)。

問題

而問題就來了。。。

14907957629836.jpg

isHidden 居然是個 UIBindingObserver<UIView, Bool>

嘗試使用 KVO

我在使用 OC 時,會使用 ReactiveCocoa 。而在 ReactiveCocoa 我經(jīng)常使用 KVO 去監(jiān)控屬性。或者在 RxSwift 也有類似的方法吧?

14907963190486.jpg

好像的確有類似的東西,那就到源碼中查看怎么使用吧。。。

14907966551999.jpg

從這些注釋,大概知道了使用方法,那就開干吧。。。

14907975018713.jpg

只打印了 next(Optional(false)), 并不能監(jiān)控到 isHidden 值的變化=。=

為什么呢?難道我使用方法不對?找找可參照的例子。
KVOObservableTests.swift 找到了一段測試代碼:

14907981189220.jpg

注意,這里的屬性都使用了 dynamic , 感覺好像抓到了些什么?先嘗試定義一個類試試看。

14907963190486.jpg

起作用了??,那把 dynamic 刪了呢?

14907984225211.jpg

又不好使了?? 為什么呢?
其實喵神在《Swift 開發(fā)必備 Tips》中就提過這個問題。

14907990537387.jpg

所以,只能另想辦法了??

使用 methodInvoked

還記得 UITextField 經(jīng)常使用的 text 屬性么?它又是怎么實現(xiàn)的呢?

14907995154959.jpg

查看源碼,發(fā)現(xiàn)它使用了 UIControlvalue 方法。繼續(xù)往下看。。。

14907997006995.jpg

這里是通過監(jiān)控控件事件來實現(xiàn)的。。??那么 textField.rx.text.subscribe 同樣存在一個問題

textField.text = "test"

這樣的操作,也是沒法得到事件的。。

但可以從這個段代碼中得到給啟發(fā),我是否可以通過訂閱方法處理來完成我想要的需求呢?我們在設(shè)置屬性時必然會走 set 方法。

14908003089486.jpg

嗯,這個好像是我們需要的方法,那就看看能否實現(xiàn)吧。

14908006443769.jpg

好像起作用了,但我們可以做進(jìn)一步的優(yōu)化。我希望事件就給我返回個 Bool,而且包含一開始的默認(rèn)屬性。

14908009585593.jpg

這樣就得到我想要的結(jié)果了??,但我可以讓它變得更好用點,把它封裝到 rx 中作為一個 hidden 屬性好了

extension Reactive where Base: UIView {
    
    var hidden: Observable<Bool> {
        return self.methodInvoked(#selector(setter: self.base.isHidden))
            .map { event -> Bool in
                guard let isHidden = event.first as? Bool else {
                    fatalError()
                }
                
                return isHidden
            }
            .startWith(self.base.isHidden)
    }
    
    
}
14908014060346.jpg

嗯,現(xiàn)在就可以愉快的訂閱 hidden 屬性了 (^-^)V

如果大家有更好的方法,歡迎分享討論。

最后:歡迎討論、批評、指錯。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容