DKDataSources
DKDataSource 是您解决在 TableViews 和 CollectionViews 中多重 cell 类型常见问题的整洁方案,也为在 cellForRow、heightForRow 等中的 if indexPath.section == 0 等类似语句提供了优雅的解决方案。
这是第一张截图中的 ViewController 代码。
lazy var dataSource = DKTableDataSource<CellType>(
models: [
DisclosureCellModel(title: "Disclosure 1", action: .action1),
TextFieldCellModel(title: "TextField 1", placeholder: "Placeholder 1"),
SwitchCellModel(title: "Switch 1", isOn: true),
BannerCellModel(imageName: "placeholder"),
SwitchCellModel(title: "Switch 2", isOn: false),
BannerCellModel(imageName: "placeholder"),
DisclosureCellModel(title: "Disclosure 2", action: .action2),
TextFieldCellModel(title: "TextField 2", placeholder: "Placeholder 2"),
BannerCellModel(imageName: "placeholder")
]
)
// in `viewDidLoad`
dataSource.registerCells(for: tableView)
tableView.dataSource = dataSource示例
要运行示例项目,请克隆仓库,并首先从 Example 目录运行 pod install
安装
DKDataSources 通过 CocoaPods 提供。安装它,只需将以下行添加到您的 Podfile 中
pod 'DKDataSources'用法
在您使用 DKDataSources 时,需要满足一些要求使其正常工作。首先,您需要一个符合 DKCellType 协议的 enum。这个 enum 将包含所有可能的 cells 以及为注册和回收的每个 cell 的附加信息。
enum CellType: DKCellType {
case `switch`(SwitchCellModel)
var info: (cellClass: AnyClass, identifier: String) {
switch self {
case .switch:
return (cellClass: SwitchCell.self, identifier: NSStringFromClass(SwitchCell.self))
}
}每个 cell 都需要一个对应的 model 进行配置。这个模型需要继承自通用类 DKCellModel<>,其中类型是您之前创建的 enum,所以目前是 DKCellModel<CellType>。然后您需要 override 属性 type 并将其设置为对应的 cell 类型。在这种情况下,CellType.switch 与类型为 SwitchCellModel 的关联值相关联,所以我们传递那里 self。
final class SwitchCellModel: DKCellModel<CellType> {
override var type: CellType { .switch(self) }
let title: String
var isOn: Bool
init(title: String, isOn: Bool) {
self.title = title
self.isOn = isOn
}
}您有了 CellType 和 CellModel 后,现在您需要的仅仅是您的 cell(显然)。每个 cell 都需要符合 DKTableConfigurableCell 协议,这将迫使您实现 configure(它在 cellForRow 中被调用),您还需要将模型 cast 到您的 cell 对应的模型,这样您就可以访问具体的属性。
extension SwitchCell: DKTableConfigurableCell {
func configure<T>(with model: T) where T : DKCellModelProtocol {
guard let model = model as? SwitchCellModel else { return assertionFailure() }
titleLabel.text = model.title
switchView.isOn = model.isOn
}
}现在您已经完成了。而且这就是您在控制器中实现无限类型 cell 所需要做的全部事情,甚至是单个生命周期。
lazy var dataSource = DKTableDataSource<CellType>(
models: [
TextFieldCellModel(title: "TextField 1", placeholder: "Placeholder 1"),
SwitchCellModel(title: "Switch 1", isOn: true)
])
// in `viewDidLoad`
dataSource.registerCells(for: tableView)
tableView.dataSource = dataSourceDKTableDataSource 在初始化器中为所有 UITableViewDataSource 方法提供了闭包,如果需要,您可以在那里做一些额外的设置。
lazy var dataSource = DKTableDataSource<CellType>(
models: [
SwitchCellModel(title: "Switch 1", isOn: true),
],
configureCell: { (model, cell) in
if let cell = cell as? SwitchCell {
cell.delegate = self
}
cell.configure(with: model)},
titleForHeaderInSection: { _, section in "Section Header Title" },
titleForFooterInSection: { _, section in "Section Footer Title" },
canEditRowAtIndexPath: { _, indexPath in false },
canMoveRowAtIndexPath: { _, indexPath in false }
)包含更多区段的TableView
只需使用下面的 DKSectionedTableViewDataSource<>。
lazy var section1DataSource = DKTableDataSource<CellType>(
models: [
DisclosureCellModel(title: "Disclosure 1", action: .action1),
SwitchCellModel(title: "Switch 1", isOn: true),
])
lazy var section2DataSource = DKTableDataSource<CellType>(
models: [
BannerCellModel(imageName: "placeholder"),
])
lazy var dataSource = DKSectionedTableViewDataSource<CellType>(
dataSources: [section1DataSource, section2DataSource]
)
// in `viewDidLoad`
dataSource.registerCells(for: tableView)
tableView.dataSource = dataSourceDKSectionedTableViewDataSource 还在初始化器中提供了闭包。
lazy var dataSource = DKSectionedTableViewDataSource<CellType>(
dataSources: [section1DataSource, section2DataSource, section3DataSource],
configureCell: { (model, cell) in
if let cell = cell as? SwitchCell {
cell.delegate = self
}
cell.configure(with: model)},
sectionIndexTitles: { _ in ["A", "B", "C"] },
sectionForSectionIndexTitle: { _, title, index in index }
)集合视图
所有东西都可以与TableView相同,但您需要使用
DKCollectionConfigurableCell而不是DKTableConfigurableCellDKCollectionDataSource而不是DKTableDataSourceDKSectionedCollectionDataSource而不是DKSectionedTableViewDataSource
所有情况都在示例项目中得到覆盖。
作者
Denis Kakaca, [email protected]
许可证
DKDataSources 在 MIT 许可证下可用。有关更多信息,请参阅 LICENSE 文件。
