Swift - RxSwift的使用详解56(结合MJRefresh使用1:下拉刷新)
作者:hangge | 2018-05-04 09:44
MJRefresh 是一个使用 Objective-C 编写的刷新库,使用简单,功能强大。它既可以实现下拉刷新,也能实现上拉加载。本文通过样例演示如何让 RxSwift 与 MJRefresh 结合使用。
一、准备工作
1,配置 MJRefresh
关于 MJRefresh 的安装配置和相关介绍,可以参考我之前写的这篇文章:
2,对 MJRefresh 进行扩展
为了让 MJRefresh 可以更好地与 RxSwift 配合使用,我这里对它进行扩展(MJRefresh+Rx.swift),内容如下:
- 将下拉、上拉的刷新事件转为 ControlEvent 类型的可观察序列。
- 增加一个用于停止刷新的绑定属性。
import RxSwift import RxCocoa //对MJRefreshComponent增加rx扩展 extension Reactive where Base: MJRefreshComponent { //正在刷新事件 var refreshing: ControlEvent<Void> { let source: Observable<Void> = Observable.create { [weak control = self.base] observer in if let control = control { control.refreshingBlock = { observer.on(.next(())) } } return Disposables.create() } return ControlEvent(events: source) } //停止刷新 var endRefreshing: Binder<Bool> { return Binder(base) { refresh, isEnd in if isEnd { refresh.endRefreshing() } } } }
3,网络请求服务
这里专门封装了一个网络请求服务层(NetworkService.swift),作用是当表格发生上拉、或下拉时,通过它获取数据。为了方便演示,这里没有真正去发起网络请求,而是随机生成 15 条数据,并延迟 1 秒返回。
import RxSwift import RxCocoa //网络请求服务 class NetworkService { //获取随机数据 func getRandomResult() -> Driver<[String]> { print("正在请求数据......") let items = (0 ..< 15).map {_ in "随机数据\(Int(arc4random()))" } let observable = Observable.just(items) return observable .delay(1, scheduler: MainScheduler.instance) .asDriver(onErrorDriveWith: Driver.empty()) } }
二、下拉刷新的样例
1,效果图
(1)页面打开后自动会加载 15 条数据,并显示在表格中。
(2)而每次下拉表格又会随机生成 15 条新的数据,并替换表格里的原数据。
2,样例代码
(1)ViewModel.swift
主要是根据下拉刷新事件序列去查询数据,同时数据返回后除了生成表格数据序列外,还有个停止刷新状态的序列。
import RxSwift import RxCocoa class ViewModel { //表格数据序列 let tableData:Driver<[String]> //停止刷新状态序列 let endHeaderRefreshing: Driver<Bool> //ViewModel初始化(根据输入实现对应的输出) init(headerRefresh: Driver<Void>) { //网络请求服务 let networkService = NetworkService() //生成查询结果序列 self.tableData = headerRefresh .startWith(()) //初始化完毕时会自动加载一次数据 .flatMapLatest{ _ in networkService.getRandomResult() } //也可考虑改用flatMapFirst //生成停止刷新状态序列 self.endHeaderRefreshing = self.tableData.map{ _ in true } } }
(2)ViewController.swift
ViewModel 初始化后,将表格数据序列绑定到 tableView 上显示数据,同时将停止刷新序列绑定到 tableView 的 mj_header 上让其自动停止刷新。
import UIKit import RxSwift import RxCocoa class ViewController: UIViewController { //表格 var tableView:UITableView! let disposeBag = DisposeBag() override func viewDidLoad() { super.viewDidLoad() //创建表格视图 self.tableView = UITableView(frame: self.view.frame, style:.plain) //创建一个重用的单元格 self.tableView!.register(UITableViewCell.self, forCellReuseIdentifier: "Cell") self.view.addSubview(self.tableView!) //设置头部刷新控件 self.tableView.mj_header = MJRefreshNormalHeader() //初始化ViewModel let viewModel = ViewModel(headerRefresh: self.tableView.mj_header.rx.refreshing.asDriver()) //单元格数据的绑定 viewModel.tableData.asDriver() .drive(tableView.rx.items) { (tableView, row, element) in let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")! cell.textLabel?.text = "\(row+1)、\(element)" return cell } .disposed(by: disposeBag) //下拉刷新状态结束的绑定 viewModel.endHeaderRefreshing .drive(self.tableView.mj_header.rx.endRefreshing) .disposed(by: disposeBag) } }
全部评论(1)
3.6.1没有Binder该如何处理
站长回复:建议升级成最新版本的。