RxDataSource 的简单使用

本文最后更新于 2021年4月4日 晚上

记录 RxDataSource 的简单使用过程, 特别是用在 TableView 的时候.

RxDataSource 的简单使用

用到的库: RxDataSources.

整个使用流程如下所示:

  1. 定义 Section 和 Cell 的数据结构:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    /// Section 模型
    struct AddNewAddressViewCellNormalSection {
    var header: String
    var items: [AddNewAddressViewCellType]
    }

    /// 扩展 Section 模型, 让其遵守 SectionModelType 协议, 以便数据源使用
    extension AddNewAddressViewCellNormalSection: SectionModelType {
    init(original: AddNewAddressViewCellNormalSection, items: [AddNewAddressViewCellType]) {
    self = original
    self.items = items
    }
    }

    /// 多种类型 Cell 数据模型定义
    enum AddNewAddressViewCellType {
    case textAndTextField(String, String, String, Bool)
    case textAndSwitch(String, Bool)
    }

    上面代码中定义了一个 TableView 中的 Section 模型, 这个模型必须要有的存储属性是 items, 其中的元素类型就是 Cell 的模型.

  2. 定义好数据结构后, 就可以组装数据了. 数据可以通过 Variable 来提供(当然也可以用 PublishSubject 等 Subject, 比如要网络获取数据的情况):

    1
    2
    3
    4
    5
    6
    7
    8
    let celldata = Variable<[AddNewAddressViewCellNormalSection]>([
    // section0
    AddNewAddressViewCellNormalSection(header: "", items:
    [.textAndTextField("收货人", "", "输入收件人姓名", false),
    .textAndTextField("手机号码", "", "输入收件人手机号", false),
    // section1
    AddNewAddressViewCellNormalSection(header: "", items: [.textAndSwitch("设置为默认收货地址", false)])
    ])

    上面的数据中定义了两个 section, 且每个 section 中使用的都是不同的 cell 数据模型.

  3. 设置 TableView 的数据源和代理:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    // 绑定数据源
    viewModel.celldata.asObservable()
    .bind(to: _tableView.rx.items(dataSource: getDataSource())).disposed(by: _disposeBag)

    // 设置代理
    _tableView.rx.setDelegate(self).disposed(by: _disposeBag)

    // 其中的 getDataSource() 方法如下所示:

    private func getDataSource() -> RxTableViewSectionedReloadDataSource<AddNewAddressViewCellNormalSection> {
    return RxTableViewSectionedReloadDataSource<AddNewAddressViewCellNormalSection>(
    configureCell: { dataSource, tableView, indexPath, item in
    switch item {
    case .textAndTextField(let labelText, let content, let placeHolder, let showClosure):
    // dequeue cell 并根据 item 配置 cell
    case .textAndSwitch(let labelText, let isOn):
    // dequeue cell 并根据 item 配置 cell
    }
    })
    }

通过上述方式设置后, 如果要更新数据, 只要在之前创建的 celldata (类型是 Subject 中的一种) 上更新最新数据, 则 TableView 便可以同步更新.

若 tableView 有其他的设置, 可以在 tableView 上直接进行, 也可以在代理中处理:

1
2
3
4
5
6
7
8
_tableView.isScrollEnabled = false
_tableView.tableFooterView = UIView()
_tableView.backgroundColor = .clear
_tableView.rowHeight = 45
_tableView.register(AddNewAddressViewEditableCell.self,
forCellReuseIdentifier: AddNewAddressViewEditableCell.reuseID)
_tableView.register(AddNewAddressViewSwitchableCell.self,
forCellReuseIdentifier: AddNewAddressViewSwitchableCell.reuseID)

注意数据源中的类型是 Section 数组, 而非 Section 类型! 否则编译会报错.

如果要将 cell 上的一些控件点击都绑定到控制器对应的视图模型上, 则需要在配置数据源的时候进行处理.


RxDataSource 的简单使用
https://blog.rayy.top/2019/01/06/2019-25-rxdatasource/
作者
貘鸣
发布于
2019年1月6日
许可协议