RxSwift 对 MJRefresh 的封装
2017-11-04 本文已影响18人
OHeroJ
对于一个很常用的两个库, MJRefresh 如何可以像 UIButton 使用方式呢:
btn.rx.tap.subscribe(...)
Rxswift 中的很多类似处理的方式都使用了跟下面极为相似的代码,进行针对 UIControl
类似的的适配时,是通过一个中间层 ControlTarget, 或者是继承自RxTarget
的子类来完成的,为了保持类似这个 ControlTarget 实例的存活,使得它不会被自动释放,先用一个集合来包裹住它,并将这个集合设置为目标 UIControl 的关联对象。这个 ControlTarget 看做是这个事件流管道中的一个资源来生成 Observable
对象
个人写的代码如下:
import UIKit
import MJRefresh
import RxSwift
import RxCocoa
class RxTarget: NSObject, Disposable {
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.rx.setDelegate(self).disposed(by: disposeBag)
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