之前寫(xiě)過(guò)兩篇RxSwift在UITableView中使用的文章古掏,一篇是RXSwift在UITableView中的基本使用帜平,另一篇是Moya + RXSwift + HandyJSONUITableView中的使用吟温,有興趣的朋友可以看一下這兩篇文章
【RxSwift系列】RXSwift在UITableView中使用(一) http://www.reibang.com/p/4d9447d5278a
【RxSwift系列】Moya + RXSwift + HandyJSON在UITableView中的使用(二)http://www.reibang.com/p/fe36da1267cd
今天主要講的是用RxSwift基于MJRefresh在UITableView中實(shí)現(xiàn)下拉刷新拗馒,上拉加載,首先創(chuàng)建一個(gè)枚舉溯街,設(shè)置刷新的幾種狀態(tài)
enum RefreshStatus: Int {
case InvalidData // 無(wú)效的數(shù)據(jù)
case DropDownSuccess // 下拉成功
case PullSuccessHasMoreData // 上拉诱桂,還有更多數(shù)據(jù)
case PullSuccessNoMoreData // 上拉,沒(méi)有更多數(shù)據(jù)
}
在viewModel中可以添加一個(gè)與刷新有關(guān)的變量
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是一個(gè)variable類(lèi)型,它是一個(gè)泛型,它的.value屬性指向的就是它的實(shí)際參數(shù)類(lèi)型呈昔。例子中挥等,variable的實(shí)際參數(shù)類(lèi)型是RefreshStatus,它是一個(gè)枚舉類(lèi)型堤尾。variable類(lèi)型的特點(diǎn)在于肝劲,只要改變value的值,就會(huì)發(fā)射改變后的數(shù)據(jù)郭宝,所以在viewModel里面改變r(jià)efreshStatus的值辞槐,就可以響應(yīng)刷新。
接下來(lái)在viewModel中實(shí)現(xiàn)請(qǐng)求的方法
override init() {
super.init()
//待錄入請(qǐng)求
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 {
//處理返回的數(shù)據(jù)粘室,給dataSource賦值
self?.refreshStatus.value = .DropDownSuccess
} else {
//處理返回的數(shù)據(jù)榄檬,給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中綁定數(shù)據(jù)請(qǐng)求
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
}
//數(shù)據(jù)綁定
viewModel.result?
.bind(to: listTableView.rx.items(dataSource: dataSource))
.addDisposableTo(disposeBag)
//改變刷新?tīng)顟B(tài)
viewModel.refreshStatus.asObservable().subscribe(onNext: { (status) in
self.refreshStatus(status: status,tableView: self.listTableView)
}).addDisposableTo(disposeBag)
listTableView.mj_header.beginRefreshing()
//cell點(diǎn)擊事件
listTableView.rx.modelSelected(SystemMessgeDataModel.self).subscribe(onNext: { (model) in
})
.addDisposableTo(disposeBag)
}
/**
設(shè)置刷新?tīng)顟B(tài)
*/
func refreshStatus(status:RefreshStatus,tableView: UITableView) {
switch status {
case .InvalidData: // 無(wú)效的數(shù)據(jù)
tableView.mj_header.endRefreshing()
tableView.mj_footer.endRefreshing()
return
case .DropDownSuccess: // 下拉成功
tableView.mj_header.endRefreshing()
tableView.mj_footer.resetNoMoreData()
case .PullSuccessHasMoreData: // 上拉,還有更多數(shù)據(jù)
tableView.mj_footer.endRefreshing()
case .PullSuccessNoMoreData: // 上拉衔统,沒(méi)有更多數(shù)據(jù)
tableView.mj_footer.endRefreshingWithNoMoreData()
}
tableView.mj_header.endRefreshing()
}
}