Braid 是一个功能丰富的库,用于使您的表视图设置流程更小、更声明式、更类型安全,并且更简单有趣。它包括自动比较和动画表据、允许单元格发出自定义事件以及支持 RxSwift。
快速入门
使用 Braid,您可以将数据和功能(如数据、单元格类型(或提供单元格的闭包)和事件处理器)绑定到您的表(每个部分基础上,或者如果您的表不是分区的,则绑定到整个表)。
对于分区的表,我们首先声明一个枚举(或结构体),定义您的分区,并创建一个“绑定器”对象
enum Section: TableViewSection {
case first
case second
case third
case fourth
}
let binder = SectionedTableViewBinder(tableView: self.tableView, sectionedBy: Section.self)
然后,我们开始为一个或多个分区创建“绑定链”,类似于 switch 语句。绑定链是我们将数据(单元格类型、模型类型、事件处理器等)绑定到我们的表的方式。在这里,我们将创建三个“绑定链”以演示如何将一个(或多个!)单元格和模型类型绑定到我们的分区,以及如何添加标题和单元格高度。
var myModels: [MyModel] = ...
binder.onSection(.first)
.bind(headerTitle: "FIRST")
.bind(cellType: MyCustomTableViewCell.self, models: { myModels })
.onDequeue { (row: Int, cell: MyCustomTableViewCell, model: MyModel) in
// setup the dequeued 'cell' with the 'model'
}
.onTapped { (row, cell, model: MyModel) in
// e.g. go to a detail view controller with the 'model'
}
binder.onSections(.second, .third)
.bind(headerTitles: [.second: "SECOND", .third: "THIRD"])
.bind(cellProvider: { (tableView, section, row, model: Any) -> UITableViewCell in
if let model = model as? Int {
return tableView.dequeue(MyOtherTableViewCell.self)
} else if let model = model as? String {
return tableView.dequeue(MyCustomTableViewCell.self)
}
...
}, models: { () -> [Section: [Any]]
return [.second: [1, "hello", 67, 42], .third: [81, 7, "world"]
})
...
binder.onAllOtherSections()
.bind(cellType: MyOtherOtherTableViewCell.self, viewModels: { ... })
...
binder.finish()
单元格会根据给定的“模型”数组自动 dequeue,而绑定的模型和单元格类型将被记住,并传递给绑定链上的其他处理器。您也不需要做任何账目记录来记住哪个分区对应于哪个整数 - 您可以动态地删除或重新排列多个显示的分区,并且它会在内部跟踪命名分区在表上的移动位置。
更新表视图也非常简单 - 当提供给 models
闭包的数据发生变化时,只需在绑定器上调用 refresh
方法,它将比较和动画更改。
自定义单元格事件
确定如何传递事件,例如按钮按下或单元格内输入文本,回传至视图控制器,这始终是一个麻烦事,通常需要遵守大量的不同委托协议。为了解决这个问题,Braid还赋予你让你的单元格声明自定义事件枚举的能力,这些枚举可以在你的绑定链上进行观察。这是通过使你的单元格遵守ViewEventEmitting
协议并向其提供一个ViewEvent
枚举来实现的,如下所示
class MyCustomTableViewCell: UITableViewCell, ViewEventEmitting {
enum ViewEvent {
case switchToggled(state: Bool)
case buttonPressed
case textEntered(text: String)
}
@objc func onSwitchToggled(switch: UISwitch) {
self.emit(event: .switchToggled(state: switch.isOn)
}
}
然后你可以观察单元格在绑定链上发射事件的情况,如下
binder.onSection(.first)
.bind(cellType: MyCustomTableViewCell.self, models: { myModels })
.onEvent(from: MyCustomTableViewCell.self) { (row, cell, event, model: MyModel) in
switch event {
case .switchToggled(let state):
// update something in the model
case .buttonPressed:
// perform some action
case .textEntered(let text):
// update something in the model
}
}
差异和动画
Braid支持数据变化时对表格进行深度差异处理和自动动画。无需对模型进行特殊处理,Braid就可以确定哪些部分更新了,并运行基本计数以对部分应用'reload'、'insert'和'delete'动画。
然而,如果你想这样做,该库还通过考虑对你绑定的模型遵守Equatable
和CollectionIdentifiable
来提供更强大的差异控制,并提供更精确的'reload'、'insert'和'delete'动画以及跟踪移动。这种'分级差异处理'是针对每个部分进行的,所以如果一个部分的模型遵守这些协议而另一个部分的模型不遵守,Braid还可以仅对前一个部分进行更高级的差异处理。
高级特性
尽管你是一名优秀的开发者,但你来看这些示例时,会意识到可能会有哪些限制和边缘情况。幸运的是,Braid支持许多更多的高级特性,可以覆盖这些情况,并且随着表格的复杂性而扩展,所以你永远不会受到该库的限制,以至于不得不求助于常规的UIKit 'dataSource/delegate'模式。
Braid得到了全面文档的说明,包括在仓库中'BraidExample' Xcode项目中的教程和工作示例代码(附带文档说明!)。以下列出已提供的教程,以帮助你熟悉Braid:
将支持集合视图,并能够像部分一样通过名称绑定单元格,以实现对表单风格表格的绑定。
安装
Braid可以通过CocoaPods获取。要安装它,只需将以下行添加到Podfile
pod 'Braid'
如果您在Braid中使用RxSwift,必须包含Braid的Rx子组件,如下所示
pod 'Braid/Rx'
贡献者
Aaron Bosnjak(邮箱:[email protected],Twitter:@aaron_bosnjak)
Braid欢迎贡献者!如果您有功能想法或错误修复,请随时发起拉取请求。问题和功能想法在Trello板上进行跟踪。
致谢
Braid使用了Tony Arnold的极其出色Differ库的一个分支来执行其比较工作。如果您喜欢Braid,确保也给那个仓库点个star!
许可证
Braid在MIT许可证下提供,因此可以用它来基本上做任何你想要的事情。有关更多信息,请参阅LICENSE文件。