美文网首页RXswiftRxSwift学习iOS Dev
【RxSwift系列】RxSwift下基于MJRefresh实现

【RxSwift系列】RxSwift下基于MJRefresh实现

作者: yuanweiphone | 来源:发表于2017-09-04 14:12 被阅读231次

    之前写过两篇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()
        }
    
    }
    

    相关文章

      网友评论

      • 再见远洋:请问楼主 现在是不是不需要用handjson这个库了?我看你这篇文章直接用系统的JSONSerialization做的 也没看到转模型的方法 是要在子类中去转模型吗?
        yuanweiphone: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)!
        }

        在处理返回的数据,给dataSource赋值这个位置,用handyjson去转模型
      • Hengry:精彩

      本文标题:【RxSwift系列】RxSwift下基于MJRefresh实现

      本文链接:https://www.haomeiwen.com/subject/wycejxtx.html