之前写过两篇RxSwift在UITableView中使用的文章,一篇是RXSwift在UITableView中的基本使用,另一篇是Moya + RXSwift + HandyJSONUITableView中的使用,有兴趣的朋友可以看一下这两篇文章
【RxSwift系列】RXSwift在UITableView中使用(一) http://www.jianshu.com/p/4d9447d5278a
【RxSwift系列】Moya + RXSwift + HandyJSON在UITableView中的使用(二)http://www.jianshu.com/p/fe36da1267cd
今天主要讲的是用RxSwift基于MJRefresh在UITableView中实现下拉刷新,上拉加载,首先创建一个枚举,设置刷新的几种状态
enum RefreshStatus: Int {
case InvalidData // 无效的数据
case DropDownSuccess // 下拉成功
case PullSuccessHasMoreData // 上拉,还有更多数据
case PullSuccessNoMoreData // 上拉,没有更多数据
}
在viewModel中可以添加一个与刷新有关的变量
class BaseViewModel: NSObject {
let disposeBag = DisposeBag()
var refreshStatus = Variable(RefreshStatus.InvalidData)
var loadData = PublishSubject<Int>()
var dataSource = [SectionModel<String, BaseDataModel>]()
var result: Observable<[SectionModel<String, BaseDataModel>]>?
var page:Int = 1
}
refreshStatus是一个variable类型,它是一个泛型,它的.value属性指向的就是它的实际参数类型。例子中,variable的实际参数类型是RefreshStatus,它是一个枚举类型。variable类型的特点在于,只要改变value的值,就会发射改变后的数据,所以在viewModel里面改变refreshStatus的值,就可以响应刷新。
接下来在viewModel中实现请求的方法
override init() {
super.init()
//待录入请求
result = loadData.flatMapLatest({ [weak self] (p) -> Observable<[SectionModel<String, BaseDataModel>]> in
return provider.request(.list(pageNumber: p)).map({ (x) -> [SectionModel<String, BaseDataModel>] in
guard let json = try? JSONSerialization.jsonObject(with: x.data, options: JSONSerialization.ReadingOptions(rawValue: 0)) as! [String: Any] else {
return [SectionModel(model: "", items: [])]
}
if let dic = json["data"] {
if p == 1 {
//处理返回的数据,给dataSource赋值
self?.refreshStatus.value = .DropDownSuccess
} else {
//处理返回的数据,给dataSource赋值
if array.count <= 0 {
self?.refreshStatus.value = .PullSuccessNoMoreData
} else {
self?.refreshStatus.value = .PullSuccessHasMoreData
}
}
return (self?.dataSource)!
} else {
if p != 1 {
self?.page -= 1
}
self?.refreshStatus.value = .InvalidData
}
return [SectionModel(model: "", items: [])]
}).catchErrorJustReturn([SectionModel(model: "", items: [])])
})
}
//MARK: 下拉刷新
func reloadData() {
page = 1
loadData.onNext(page)
}
//MARK: 上拉加载更多
func loadMoreData() {
page += 1
loadData.onNext(page)
}
然后在Controller中绑定数据请求
class BaseViewController: UIViewController {
var identifier = "identifier"
let disposeBag = DisposeBag()
let dataSource = RxTableViewSectionedReloadDataSource<SectionModel<String,BaseDataModel>>()
let viewModel = BaseViewModel()
lazy var listTableView: UITableView = {
let listTableView = UITableView(frame: CGRect.zero, style: .plain)
listTableView.frame = CGRect(x: 0, y: 0, width: ScreenWidth, height: ScreenHeight)
listTableView.separatorStyle = .none
listTableView.rowHeight = 47
return listTableView
}()
override func viewDidLoad() {
super.viewDidLoad()
mainView.addSubview(listTableView)
listTableView.register(BaseTableViewCell.self, forCellReuseIdentifier: identifier)
listTableView.mj_header = MJRefreshStateHeader(refreshingBlock: {
self.viewModel.reloadData()
})
listTableView.mj_footer = MJRefreshBackNormalFooter(refreshingBlock: {
self.viewModel.loadMoreData()
})
dataSource.configureCell = {
_, tableView, indexPath, model in
let cell = tableView.dequeueReusableCell(withIdentifier: self.identifier, for: indexPath) as! BaseTableViewCell
return cell
}
//数据绑定
viewModel.result?
.bind(to: listTableView.rx.items(dataSource: dataSource))
.addDisposableTo(disposeBag)
//改变刷新状态
viewModel.refreshStatus.asObservable().subscribe(onNext: { (status) in
self.refreshStatus(status: status,tableView: self.listTableView)
}).addDisposableTo(disposeBag)
listTableView.mj_header.beginRefreshing()
//cell点击事件
listTableView.rx.modelSelected(SystemMessgeDataModel.self).subscribe(onNext: { (model) in
})
.addDisposableTo(disposeBag)
}
/**
设置刷新状态
*/
func refreshStatus(status:RefreshStatus,tableView: UITableView) {
switch status {
case .InvalidData: // 无效的数据
tableView.mj_header.endRefreshing()
tableView.mj_footer.endRefreshing()
return
case .DropDownSuccess: // 下拉成功
tableView.mj_header.endRefreshing()
tableView.mj_footer.resetNoMoreData()
case .PullSuccessHasMoreData: // 上拉,还有更多数据
tableView.mj_footer.endRefreshing()
case .PullSuccessNoMoreData: // 上拉,没有更多数据
tableView.mj_footer.endRefreshingWithNoMoreData()
}
tableView.mj_header.endRefreshing()
}
}
网友评论
if p == 1 {
//处理返回的数据,给dataSource赋值
self?.refreshStatus.value = .DropDownSuccess
} else {
//处理返回的数据,给dataSource赋值
if array.count <= 0 {
self?.refreshStatus.value = .PullSuccessNoMoreData
} else {
self?.refreshStatus.value = .PullSuccessHasMoreData
}
}
return (self?.dataSource)!
}
在处理返回的数据,给dataSource赋值这个位置,用handyjson去转模型