Swift - RxSwift的使用詳解56(結合MJRefresh使用1:下拉刷新)

MJRefresh 是一個使用 Objective-C 編寫的刷新庫,使用簡單,功能強大。它既可以實現下拉刷新,也能實現上拉加載。本文通過樣例演示如何讓 RxSwiftMJRefresh 結合使用。

一、準備工作

1,配置 MJRefresh

關于 MJRefresh 的安裝配置和相關介紹,可以參考這篇文章:

2,對 MJRefresh 進行擴展

為了讓 MJRefresh 可以更好地與 RxSwift 配合使用,我這里對它進行擴展(MJRefresh+Rx.swift),內容如下:

  • 將下拉、上拉的刷新事件轉為 ControlEvent 類型的可觀察序列。
  • 增加一個用于停止刷新的綁定屬性。
import RxSwift
import RxCocoa
 
//對MJRefreshComponent增加rx擴展
extension Reactive where Base: MJRefreshComponent {
     
    //正在刷新事件
    var refreshing: ControlEvent<Void> {
        let source: Observable<Void> = Observable.create {
            [weak control = self.base] observer  in
            if let control = control {
                control.refreshingBlock = {
                    observer.on(.next(()))
                }
            }
            return Disposables.create()
        }
        return ControlEvent(events: source)
    }
     
    //停止刷新
    var endRefreshing: Binder<Bool> {
        return Binder(base) { refresh, isEnd in
            if isEnd {
                refresh.endRefreshing()
            }
        }
    }
}

3,網絡請求服務

這里專門封裝了一個網絡請求服務層(NetworkService.swift),作用是當表格發生上拉、或下拉時,通過它獲取數據。為了方便演示,這里沒有真正去發起網絡請求,而是隨機生成 15 條數據,并延遲 1 秒返回。

import RxSwift
import RxCocoa

//網絡請求服務
class NetworkService {
     
    //獲取隨機數據
    func getRandomResult() -> Driver<[String]> {
        print("正在請求數據......")
        let items = (0 ..< 15).map {_ in
            "隨機數據\(Int(arc4random()))"
        }
        let observable = Observable.just(items)
        return observable
            .delay(1, scheduler: MainScheduler.instance)
            .asDriver(onErrorDriveWith: Driver.empty())
     }
}

二、下拉刷新的樣例

1,效果圖

(1)頁面打開后自動會加載 15 條數據,并顯示在表格中。

(2)而每次下拉表格又會隨機生成 15 條新的數據,并替換表格里的原數據。

2,樣例代碼

(1)ViewModel.swift

主要是根據下拉刷新事件序列去查詢數據,同時數據返回后除了生成表格數據序列外,還有個停止刷新狀態的序列。

import RxSwift
import RxCocoa
 
class ViewModel {
     
    //表格數據序列
    let tableData:Driver<[String]>
     
    //停止刷新狀態序列
    let endHeaderRefreshing: Driver<Bool>
     
    //ViewModel初始化(根據輸入實現對應的輸出)
    init(headerRefresh: Driver<Void>) {
         
        //網絡請求服務
        let networkService = NetworkService()
         
        //生成查詢結果序列
        self.tableData = headerRefresh
            .startWith(()) //初始化完畢時會自動加載一次數據
            .flatMapLatest{ _ in networkService.getRandomResult() }
         
        //生成停止刷新狀態序列
        self.endHeaderRefreshing = self.tableData.map{ _ in true }
    }
}

(2)ViewController.swift
ViewModel 初始化后,將表格數據序列綁定到 tableView 上顯示數據,同時將停止刷新序列綁定到 tableViewmj_header 上讓其自動停止刷新。

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()
         
        //初始化ViewModel
        let viewModel = ViewModel(headerRefresh:
            self.tableView.mj_header.rx.refreshing.asDriver())
         
        //單元格數據的綁定
        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)
    }
}

RxSwift使用詳解系列
原文出自:www.hangge.com轉載請保留原文鏈接

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容