Swift - RxSwift的使用详解57(结合MJRefresh使用2:上拉加载、以及上下拉组合)
三、上拉加载的样例
1,效果图
(1)页面打开后会自动加载 15 条数据,并显示在表格中。
(2)而每次上拉表格又会随机生成 15 条新的数据,并拼接到原数据下方显示。
2,样例代码
(1)ViewModel.swift
由于“加载更多”功能需要把新数据添加到老数据尾部,这里我使用 BehaviorRelay 作为表格数据序列,因为它可以获取到之前的数据。
import RxSwift import RxCocoa class ViewModel { //表格数据序列 let tableData = BehaviorRelay<[String]>(value: []) //停止上拉加载刷新状态序列 let endFooterRefreshing: Driver<Bool> //ViewModel初始化(根据输入实现对应的输出) init(footerRefresh: Driver<Void>, dependency: ( disposeBag:DisposeBag, networkService: NetworkService )) { //上拉结果序列 let footerRefreshData = footerRefresh .startWith(()) //初始化完毕时会自动加载一次数据 .flatMapLatest{ //也可考虑使用flatMapFirst return dependency.networkService.getRandomResult() } //生成停止上拉加载刷新状态序列 self.endFooterRefreshing = footerRefreshData.map{ _ in true } //上拉加载时,将查询到的结果拼接到原数据底部 footerRefreshData.drive(onNext: { items in self.tableData.accept(self.tableData.value + items ) }).disposed(by: dependency.disposeBag) } }
(2)ViewController.swift
ViewModel 初始化后,将表格数据序列绑定到 tableView 上显示数据。同时将停止刷新序列绑定到 tableView 的 mj_footer 上让其自动停止刷新。
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_footer = MJRefreshBackNormalFooter() //初始化ViewModel let viewModel = ViewModel( footerRefresh: self.tableView.mj_footer.rx.refreshing.asDriver(), dependency: ( disposeBag: self.disposeBag, networkService: NetworkService())) //单元格数据的绑定 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.endFooterRefreshing .drive(self.tableView.mj_footer.rx.endRefreshing) .disposed(by: disposeBag) } }
四、下拉刷新 + 上拉加载的样例
1,效果图
(1)页面打开后会自动加载 15 条数据,并显示在表格中。
(2)当下拉表格时会随机生成 15 条新的数据,并替换表格里的原数据。
(3)而当上拉表格又会随机生成 15 条新的数据,并拼接到原数据下方显示。
2,样例代码
(1)ViewModel.swift
这里同样使用 BehaviorRelay 作为表格数据序列,同时还定义了两个停止刷新序列(分别表示停止下拉刷新、停止上拉刷新)。
import RxSwift import RxCocoa class ViewModel { //表格数据序列 let tableData = BehaviorRelay<[String]>(value: []) //停止头部刷新状态 let endHeaderRefreshing: Driver<Bool> //停止尾部刷新状态 let endFooterRefreshing: Driver<Bool> //ViewModel初始化(根据输入实现对应的输出) init(input: ( headerRefresh: Driver<Void>, footerRefresh: Driver<Void> ), dependency: ( disposeBag:DisposeBag, networkService: NetworkService )) { //下拉结果序列 let headerRefreshData = input.headerRefresh .startWith(()) //初始化时会先自动加载一次数据 .flatMapLatest{ //也可考虑使用flatMapFirst return dependency.networkService.getRandomResult() } //上拉结果序列 let footerRefreshData = input.footerRefresh .flatMapLatest{ //也可考虑使用flatMapFirst return dependency.networkService.getRandomResult() } //生成停止头部刷新状态序列 self.endHeaderRefreshing = headerRefreshData.map{ _ in true } //生成停止尾部刷新状态序列 self.endFooterRefreshing = footerRefreshData.map{ _ in true } //下拉刷新时,直接将查询到的结果替换原数据 headerRefreshData.drive(onNext: { items in self.tableData.accept(items) }).disposed(by: dependency.disposeBag) //上拉加载时,将查询到的结果拼接到原数据底部 footerRefreshData.drive(onNext: { items in self.tableData.accept(self.tableData.value + items ) }).disposed(by: dependency.disposeBag) } }
(2)ViewController.swift
ViewModel 初始化后,将表格数据序列绑定到 tableView 上显示数据。同时将两个停止刷新序列分别绑定到 tableView 的 mj_header 和 mj_footer 上让其自动停止刷新。
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() //设置尾部刷新控件 self.tableView.mj_footer = MJRefreshBackNormalFooter() //初始化ViewModel let viewModel = ViewModel( input: ( headerRefresh: self.tableView.mj_header.rx.refreshing.asDriver(), footerRefresh: self.tableView.mj_footer.rx.refreshing.asDriver()), dependency: ( disposeBag: self.disposeBag, networkService: NetworkService())) //单元格数据的绑定 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) //上拉刷新状态结束的绑定 viewModel.endFooterRefreshing .drive(self.tableView.mj_footer.rx.endRefreshing) .disposed(by: disposeBag) } }
航哥 我请问一个问题 ,比如我每次上拉加载 时传的值不一样,应该修改哪里呢?我看到你这里每次都是请求不带参数的接口,我研究了很久目搞懂