IdentifiableType
和 Equatable
扩展你的 item,并使用 AnimatableSectionModelType
扩展你的 sectionInsert
、Reload
和 Delete
的动画类型(Automatic、Fade,...)UITableView
和 UICollectionView
编写表格视图和集合视图数据源非常繁琐。即使是最简单的情况,也需要实现大量的代理方法。
RxSwift 通过简单的数据绑定机制帮助减轻了一些负担
rx.items(dataSource:protocol<RxTableViewDataSourceType, UITableViewDataSource>)
rx.items(cellIdentifier:String)
rx.items(cellIdentifier:String:Cell.Type:_:)
rx.items(_:_:)
let data = Observable<[String]>.just(["first element", "second element", "third element"])
data.bind(to: tableView.rx.items(cellIdentifier: "Cell")) { index, model, cell in
cell.textLabel?.text = model
}
.disposed(by: disposeBag)
这对于简单的数据集效果很好,但不能处理需要绑定具有多个 section 的复杂数据集,或者需要在添加/修改/删除 item 时执行动画的情况。
这些正是 RxDataSources 旨在解决的用例。
使用 RxDataSources,编写以下代码非常容易
let dataSource = RxTableViewSectionedReloadDataSource<SectionModel<String, Int>>(configureCell: configureCell)
Observable.just([SectionModel(model: "title", items: [1, 2, 3])])
.bind(to: tableView.rx.items(dataSource: dataSource))
.disposed(by: disposeBag)
给定以下自定义数据结构
struct CustomData {
var anInt: Int
var aString: String
var aCGPoint: CGPoint
}
SectionModelType
协议的结构体Item
类型别名:等于 section 将包含的 item 的类型items
属性:类型为 Item
数组struct SectionOfCustomData {
var header: String
var items: [Item]
}
extension SectionOfCustomData: SectionModelType {
typealias Item = CustomData
init(original: SectionOfCustomData, items: [Item]) {
self = original
self.items = items
}
}
SectionOfCustomData
类型传递给它let dataSource = RxTableViewSectionedReloadDataSource<SectionOfCustomData>(
configureCell: { dataSource, tableView, indexPath, item in
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = "Item \(item.anInt): \(item.aString) - \(item.aCGPoint.x):\(item.aCGPoint.y)"
return cell
})
titleForHeaderInSection
titleForFooterInSection
dataSource.titleForHeaderInSection = { dataSource, index in
return dataSource.sectionModels[index].header
}
dataSource.titleForFooterInSection = { dataSource, index in
return dataSource.sectionModels[index].footer
}
dataSource.canEditRowAtIndexPath = { dataSource, indexPath in
return true
}
dataSource.canMoveRowAtIndexPath = { dataSource, indexPath in
return true
}
let sections = [
SectionOfCustomData(header: "First section", items: [CustomData(anInt: 0, aString: "zero", aCGPoint: CGPoint.zero), CustomData(anInt: 1, aString: "one", aCGPoint: CGPoint(x: 1, y: 1)) ]),
SectionOfCustomData(header: "Second section", items: [CustomData(anInt: 2, aString: "two", aCGPoint: CGPoint(x: 2, y: 2)), CustomData(anInt: 3, aString: "three", aCGPoint: CGPoint(x: 3, y: 3)) ])
]
Observable.just(sections)
.bind(to: tableView.rx.items(dataSource: dataSource))
.disposed(by: disposeBag)
RxDataSources 提供了两种特殊的数据源类型,可以自动处理绑定数据源中的动画更改:RxTableViewSectionedAnimatedDataSource
和 RxCollectionViewSectionedAnimatedDataSource
。
要使用其中一个动画数据源,您必须在上面概述的步骤之外再执行一些额外的步骤
AnimatableSectionModelType
IdentifiableType
:IdentifiableType
协议提供的 identity
必须是表示模型实例的不可变标识符。 例如,在 Car
模型的情况下,您可能希望使用汽车的 plateNumber
作为其身份。Equatable
:符合 Equatable
可帮助 RxDataSources
确定哪些单元格已更改,因此它可以仅对这些特定单元格进行动画处理。 这意味着,更改 Car
模型的任何属性都将触发该单元格的动画重新加载。Xcode 10.2
Swift 5.0
对于 Swift 4.x 版本,请使用版本 3.0.0 ... 3.1.0
对于 Swift 3.x 版本,请使用版本 1.0 ... 2.0.2
对于 Swift 2.3 版本,请使用版本 0.1 ... 0.9
我们将尝试保持 API 尽可能稳定,但可能会发生破坏性的 API 更改。
Podfile
pod 'RxDataSources', '~> 5.0'
Cartfile
github "RxSwiftCommunity/RxDataSources" ~> 5.0
创建一个 Package.swift
文件。
import PackageDescription
let package = Package(
name: "SampleProject",
dependencies: [
.package(url: "https://github.com/RxSwiftCommunity/RxDataSources.git", from: "5.0.0")
]
)
如果您使用的是 Xcode 11 或更高版本,请转到File / Swift Packages / Add Package Dependency...,然后输入包存储库 URL https://github.com/RxSwiftCommunity/RxDataSources.git,然后按照说明进行操作。