快速实现列表上下拉刷新
1. 创建 viewModel 类
该类继承 MGRefreshable,重载 requestMethod 获取列表接口数据,并传递给 rx 的订阅者
class MGProjectViewModel: MGRefreshable {
public var param: [String: Any]?
override func requestMethod(_ observer: (AnyObserver<Any>)) {
MGRequest.listData(MGProjectModel.self, API: MGProjectAPI.self, target: .projectList(page: currentPage, size: pageSize, param: param), success: { (data) in
observer.onNext(data)
observer.onCompleted()
}, failure: { (_, _) in
observer.onCompleted()
})
}
}
2. viewController 初始化 viewModel 并关联 tableview
startRequest 和下拉刷新的逻辑一样,但不会触发下拉的 UI 效果
let viewModel = MGProjectViewModel()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
...
viewModel.configListRefresh(tableView: tableView)
viewModel.startRequest()
}
tableview 的 cell 逻辑
extension MGProjectViewController: UITableViewDelegate, UITableViewDataSource {
//设置cell的数量
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return viewModel.dataSource.count
}
//设置tableview的cell
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: MGDefaultCellID, for: indexPath) as! MGDefaultTableViewCell
let model = viewModel.dataSource[indexPath.row] as! MGProjectModel
cell.title = model.name
return cell
}
}
组件封装源码
MGRefreshable.swift 封装上下拉刷新和监听列表数据逻辑
import UIKit
import RxSwift
protocol MGRefreshableData {
func requestMethod(_ observer: (RxSwift.AnyObserver<Any>))
}
class MGRefreshable: MGRefreshableData {
func requestMethod(_ observer: (AnyObserver<Any>)) {
}
var total: Int = 0
var currentPage: Int = 1
var pageSize: Int = 20
var isNoMore: Bool = false
var hiddenMJHeader: Bool = false
var hiddenMJFooter: Bool = false
var dataSource = Array<Any>()//列表数据源
private var refreshData = Array<Any>() {
//当前页接口数据
willSet(data) {
if (currentPage == 1) {
self.dataSource.removeAll()
}
isNoMore = data.count < self.pageSize
self.dataSource = self.dataSource + data
}
}
private var scrollView: UIScrollView?
private let disposeBag = DisposeBag()
lazy var refreshObservable = Observable.create { (observer:AnyObserver<Any>) -> Disposable in
self.requestMethod(observer)
return Disposables.create()
}
}
extension MGRefreshable {
func startRequest() {
let tableView = scrollView as! UITableView
currentPage = 1
refreshObservable.subscribe(onNext: { (obj) in
self.refreshData = obj as! [Any]
}, onCompleted: {
tableView.reloadData()
if self.dataSource.count > 0 {
tableView.setContentOffset(CGPoint.zero, animated: true)
}
if self.isNoMore {
tableView.mj_footer.endRefreshingWithNoMoreData()
}
}).disposed(by: self.disposeBag)
}
func configListRefresh(tableView: UITableView) {
scrollView = tableView
//下拉控件
if !hiddenMJHeader {
let header = MJRefreshNormalHeader.init(refreshingBlock: {
tableView.mj_footer.state = .idle
self.currentPage = 1
self.refreshObservable.subscribe(onNext: { (obj) in
self.refreshData = obj as! [Any]
}, onCompleted: {
tableView.reloadData()
tableView.mj_header.endRefreshing()
if self.isNoMore {
tableView.mj_footer.endRefreshingWithNoMoreData()
}
}).disposed(by: self.disposeBag)
})
header?.lastUpdatedTimeLabel.isHidden = true
header?.stateLabel.isHidden = true
tableView.mj_header = header
}
//上拉控件
if self.hiddenMJFooter { return }
tableView.mj_footer = MJRefreshBackNormalFooter.init(refreshingBlock: {
tableView.mj_header.state = .idle
self.currentPage += 1
self.refreshObservable.subscribe(onNext: { (obj) in
self.refreshData = obj as! [Any]
}, onCompleted: {
tableView.reloadData()
tableView.mj_header.endRefreshing()
if self.isNoMore {
tableView.mj_footer.endRefreshingWithNoMoreData()
} else {
tableView.mj_footer.endRefreshing()
}
}).disposed(by: self.disposeBag)
})
}
}