RxSwift 對 MJRefresh 使用的封裝


 

對於一個很常用的兩個庫, MJRefresh 如何可以像 UIButton 使用方式呢:

btn.rx.tap.subscribe(...)

 

Rxswift 中的很多類似處理的方式都使用了跟下面極為相似的代碼,

進行針對 UIControl的適配時,是通過一個中間層 ControlTarget來完成的,為了保持這個 ControlTarget實例的存活,使得它不會被自動釋放,先用一個集合來包裹住它,並將這個集合設置為目標 UIControl的關聯對象。此時我們可以將這個中間層 ControlTarget看做是這個事件流管道中的一個資源,這個資源的銷毀是由目標 UIControl來決定的
 
        

個人寫的代碼如下:

import UIKit
import MJRefresh
import RxSwift
import RxCocoa

class RxTarget: NSObject, Disposable {  // RxTarget 是 Rxswift 源碼
    private var retainSelf: RxTarget?
    override init() {
        super.init()
        self.retainSelf = self
    }
    func dispose() {
        self.retainSelf = nil
    }
}

final class RefreshTarget<Component:MJRefreshComponent>: RxTarget {
    typealias Callback = MJRefreshComponentRefreshingBlock
    var callback: Callback?
    weak var component:Component?

    let selector = #selector(RefreshTarget.eventHandler)

    init(_ component: Component,callback:@escaping Callback) {
        self.callback = callback
        self.component = component
        super.init()
        component.setRefreshingTarget(self, refreshingAction: selector)
    }
    @objc func eventHandler() {
        if let callback = self.callback {
            callback()
        }
    }
    override func dispose() {
        super.dispose()
        self.component?.refreshingBlock = nil
        self.callback = nil
    }
}

extension Reactive where Base: MJRefreshComponent {
    var event: ControlEvent<Base> {
        let source: Observable<Base> = Observable.create { [weak control = self.base] observer  in
            MainScheduler.ensureExecutingOnScheduler()
            guard let control = control else {
                observer.on(.completed)
                return Disposables.create()
            }
            let observer = RefreshTarget(control) {
                observer.on(.next(control))
            }
            return observer
        }.takeUntil(deallocated)
        return ControlEvent(events: source)
    }
}

 

怎么使用呢? 

 collectionView.mj_header.rx.event
            .map { _ in Reactor.Action.refresh }
            .bind(to: reactor.action)
            .disposed(by: disposeBag)
        
 collectionView.mj_footer.rx.event
            .map { _ in Reactor.Action.loadMore }
            .bind(to: reactor.action)
            .disposed(by: disposeBag)

 

更多內容,請到我的 gitpage

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM