微分器 5.0.0

Differentiator 5.0.0

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布最新发布2021年1月
SPM支持SPM

Krunoslav ZaherShai Mishali 维护。



  • Krunoslav Zaher

Travis CI

表格和集合视图数据源

特性

  • O(N) 算法用于计算差异
    • 该算法的假设是所有部分和项目都是唯一的,因此没有歧义
    • 如果有歧义,会自动回退到非动画刷新
  • 它应用额外的启发式方法以向分区视图发送最少的命令
    • 尽管运行时间是线性的,但通常发送的命令数量要远远少于线性
    • 通常(也可能是可能的)将更改的数量限制为某个小数,如果更改的数量增长到接近线性,则只能进行常规重载
  • 支持 扩展您的项目部分结构
    • 只需使用 IdentifiableTypeEquatable 扩展您的项目,并使用 AnimatableSectionModelType 扩展您的部分
  • 支持 分区和项目 两级层次动画的所有组合
    • 分区动画:插入、删除、移动
    • 项目动画:插入、删除、移动、重载(如果旧值不等于新值)
  • 可配置 InsertReloadDelete 的动画类型(自动、淡入、...)
  • 示例应用
  • 随机化压力测试(示例应用)
  • 支持开箱即用的编辑(示例应用)
  • UITableViewUICollectionView 一起工作

为什么

编写表格和集合视图数据源很乏味。即使是简单的情况,也需要实现大量的代理方法。

RxSwift通过简单的数据绑定机制帮助减轻一些负担

  1. 将数据转换为可观测序列
  2. 使用以下方法之一将数据绑定到tableView/collectionView
  • 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)

这对于简单的数据集很有效,但无法处理需要绑定具有多个区段或添加/修改/删除项目时需要执行动画的复杂数据集的情况。

这正是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)

RxDataSources example app

如何

给定以下自定义数据结构

struct CustomData {
  var anInt: Int
  var aString: String
  var aCGPoint: CGPoint
}
  1. 首先使用符合SectionModelType协议的结构定义您的区段
  • 定义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
  }
}
  1. 创建一个dataSource对象,并将其传递给您的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
})
  1. 根据需要自定义dataSource上的闭包
  • 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
}
  1. 将实际数据定义为自定义数据的 observable 序列,并将其绑定到tableView
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提供了两种特殊数据源类型,可以自动处理绑定数据源中的更改动画:RxTableViewSectionedAnimatedDataSourceRxCollectionViewSectionedAnimatedDataSource

要使用这两种动画数据源之一,需要在上述步骤的基础上再进行几个额外的步骤

  • SectionOfCustomData需要符合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 的破坏性更改仍可能发生。

CocoaPods

Podfile

pod 'RxDataSources', '~> 4.0'

Carthage

Cartfile

github "RxSwiftCommunity/RxDataSources" ~> 4.0

Swift 包管理器

创建一个 Package.swift 文件。

import PackageDescription

let package = Package(
    name: "SampleProject",
    dependencies: [
        .package(url: "https://github.com/RxSwiftCommunity/RxDataSources.git", from: "4.0.0")
    ]
)

如果您使用的是 Xcode 11 或更高版本,请转到 文件 / Swift 包 / 添加包依赖... 并输入包仓库的 URL https://github.com/RxSwiftCommunity/RxDataSources.git,然后按照说明操作。