Swift - RxSwift的使用詳解32(UITableView的使用3:刷新表格數(shù)據(jù))

很多情況下,表格里的數(shù)據(jù)不是一開始就準備好的、或者固定不變的??赡芪覀冃枰认蚍?wù)器請求數(shù)據(jù),再將獲取到的內(nèi)容顯示在表格中。
要重新加載表格數(shù)據(jù),過去的做法就是調(diào)用 tableViewreloadData() 方法。本文介紹在使用 RxSwift 的情況下,應(yīng)該如何刷新數(shù)據(jù)。

三、數(shù)據(jù)刷新

1,效果圖

(1)界面初始化完畢后,tableView 默認會加載一些隨機數(shù)據(jù)。

(2)點擊右上角的刷新按鈕,tableView 會重新加載并顯示一批新數(shù)據(jù)。

(3)為方便演示,每次獲取數(shù)據(jù)不是真的去發(fā)起網(wǎng)絡(luò)請求。而是在本地生成后延遲 2 秒返回,模擬這種異步請求的情況。

2,樣例代碼

import UIKit
import RxSwift
import RxCocoa
import RxDataSources
 
class ViewController: UIViewController {
     
    //刷新按鈕
    @IBOutlet weak var refreshButton: UIBarButtonItem!
     
    //表格
    var tableView:UITableView!
     
    let disposeBag = DisposeBag()
     
    override func viewDidLoad() {
        super.viewDidLoad()
         
        //創(chuàng)建表格視圖
        self.tableView = UITableView(frame: self.view.frame, style:.plain)
        //創(chuàng)建一個重用的單元格
        self.tableView!.register(UITableViewCell.self,
                                 forCellReuseIdentifier: "Cell")
        self.view.addSubview(self.tableView!)
         
        //隨機的表格數(shù)據(jù)
        let randomResult = refreshButton.rx.tap.asObservable()
            .startWith(()) //加這個為了讓一開始就能自動請求一次數(shù)據(jù)
            .flatMapLatest(getRandomResult)
            .share(replay: 1)
         
        //創(chuàng)建數(shù)據(jù)源
        let dataSource = RxTableViewSectionedReloadDataSource
            <SectionModel<String, Int>>(configureCell: {
                (dataSource, tv, indexPath, element) in
                let cell = tv.dequeueReusableCell(withIdentifier: "Cell")!
                cell.textLabel?.text = "條目\(indexPath.row):\(element)"
                return cell
            })
         
        //綁定單元格數(shù)據(jù)
        randomResult
            .bind(to: tableView.rx.items(dataSource: dataSource))
            .disposed(by: disposeBag)
    }
     
    //獲取隨機數(shù)據(jù)
    func getRandomResult() -> Observable<[SectionModel<String, Int>]> {
        print("正在請求數(shù)據(jù)......")
        let items = (0 ..< 5).map {_ in
            Int(arc4random())
        }
        let observable = Observable.just([SectionModel(model: "S", items: items)])
        return observable.delay(2, scheduler: MainScheduler.instance)
    }
}

3,防止表格多次刷新的說明

(1)flatMapLatest 的作用是當在短時間內(nèi)(上一個請求還沒回來)連續(xù)點擊多次“刷新”按鈕,雖然仍會發(fā)起多次請求,但表格只會接收并顯示最后一次請求。避免表格出現(xiàn)連續(xù)刷新的現(xiàn)象。

//隨機的表格數(shù)據(jù)
let randomResult = refreshButton.rx.tap.asObservable()
    .startWith(()) //加這個為了讓一開始就能自動請求一次數(shù)據(jù)
    .flatMapLatest(getRandomResult)
    .share(replay: 1)

(2)我們也對源頭進行限制下。即通過 throttle 設(shè)置個閥值(比如 1 秒),如果在1秒內(nèi)有多次點擊則只取最后一次,那么自然也就只發(fā)送一次數(shù)據(jù)請求。

//隨機的表格數(shù)據(jù)
let randomResult = refreshButton.rx.tap.asObservable()
    .throttle(1, scheduler: MainScheduler.instance) //在主線程中操作,1秒內(nèi)值若多次改變,取最后一次
    .startWith(()) //加這個為了讓一開始就能自動請求一次數(shù)據(jù)
    .flatMapLatest(getRandomResult)
    .share(replay: 1)

附:停止數(shù)據(jù)請求

? ? ? ? 在實際項目中我們可能會需要對一個未完成的網(wǎng)絡(luò)請求進行中斷操作。比如切換頁面或者分類時,如果上一次的請求還未完成就要將其取消掉。下面通過樣例演示如何實現(xiàn)該功能。

1,效果圖

? ? ? ?這里我們在前面樣例的基礎(chǔ)上增加了個“停止”按鈕。當發(fā)起請求且數(shù)據(jù)還未返回時(2 秒內(nèi)),按下該按鈕后便會停止對結(jié)果的接收處理,即表格不加載顯示這次的請求數(shù)據(jù)。

2,樣例代碼

? ? ? ?該功能簡單說就是通過 takeUntil 操作符實現(xiàn)。當 takeUntil 中的 Observable 發(fā)送一個值時,便會結(jié)束對應(yīng)的 Observable。

import UIKit
import RxSwift
import RxCocoa
import RxDataSources
 
class ViewController: UIViewController {
     
    //刷新按鈕
    @IBOutlet weak var refreshButton: UIBarButtonItem!
     
    //停止按鈕
    @IBOutlet weak var cancelButton: UIBarButtonItem!
     
    //表格
    var tableView:UITableView!
     
    let disposeBag = DisposeBag()
     
    override func viewDidLoad() {
        super.viewDidLoad()
         
        //創(chuàng)建表格視圖
        self.tableView = UITableView(frame: self.view.frame, style:.plain)
        //創(chuàng)建一個重用的單元格
        self.tableView!.register(UITableViewCell.self,
                                 forCellReuseIdentifier: "Cell")
        self.view.addSubview(self.tableView!)
         
        //隨機的表格數(shù)據(jù)
        let randomResult = refreshButton.rx.tap.asObservable()
            .startWith(()) //加這個為了讓一開始就能自動請求一次數(shù)據(jù)
            .flatMapLatest{
                self.getRandomResult().takeUntil(self.cancelButton.rx.tap)
            }
            .share(replay: 1)
         
        //創(chuàng)建數(shù)據(jù)源
        let dataSource = RxTableViewSectionedReloadDataSource
            <SectionModel<String, Int>>(configureCell: {
                (dataSource, tv, indexPath, element) in
                let cell = tv.dequeueReusableCell(withIdentifier: "Cell")!
                cell.textLabel?.text = "條目\(indexPath.row):\(element)"
                return cell
            })
         
        //綁定單元格數(shù)據(jù)
        randomResult
            .bind(to: tableView.rx.items(dataSource: dataSource))
            .disposed(by: disposeBag)
    }
     
    //獲取隨機數(shù)據(jù)
    func getRandomResult() -> Observable<[SectionModel<String, Int>]> {
        print("正在請求數(shù)據(jù)......")
        let items = (0 ..< 5).map {_ in
            Int(arc4random())
        }
        let observable = Observable.just([SectionModel(model: "S", items: items)])
        return observable.delay(2, scheduler: MainScheduler.instance)
    }
}

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 本文接著在前文樣例的基礎(chǔ)上做個功能改進,增加個實時搜索功能(本地數(shù)據(jù)篩選)。 四、數(shù)據(jù)搜索過濾 1,...
    八級大狂風(fēng)AM閱讀 4,346評論 1 2
  • 發(fā)現(xiàn) 關(guān)注 消息 RxSwift入坑解讀-你所需要知道的各種概念 沸沸騰關(guān)注 2016.11.27 19:11*字...
    楓葉1234閱讀 2,936評論 0 2
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,262評論 4 61
  • “媽媽,我需要你的愛” 今天在家里玩耍,兒子用拳頭擊中我的腰部,力道確實不小。我疼痛感來的同時靈光乍現(xiàn):我要嚇唬一...
    周京京閱讀 562評論 3 2
  • 曾經(jīng)以為7會是收筆之作,忽略了商業(yè)的重要性,那一步感情牌打出后,還要繼續(xù)賺錢。 依舊的大場面,依舊的家人主題,太多...
    慢半拍的小蝸牛閱讀 231評論 0 0

友情鏈接更多精彩內(nèi)容