Braid 1.0.3

Braid 1.0.3

Aaron Bosnjak维护。



Braid 1.0.3

  • 作者
  • Aaron Bosnjak

Braid

Build status Platform iOS Swift 5 compatible CocoaPods compatible License: MIT

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'动画。

然而,如果你想这样做,该库还通过考虑对你绑定的模型遵守EquatableCollectionIdentifiable来提供更强大的差异控制,并提供更精确的'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文件。