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 = dataSource
DKTableDataSource
在初始化器中为所有 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 = dataSource
DKSectionedTableViewDataSource
还在初始化器中提供了闭包。
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
而不是DKTableConfigurableCell
DKCollectionDataSource
而不是DKTableDataSource
DKSectionedCollectionDataSource
而不是DKSectionedTableViewDataSource
所有情况都在示例项目中得到覆盖。
作者
Denis Kakaca, [email protected]
许可证
DKDataSources 在 MIT 许可证下可用。有关更多信息,请参阅 LICENSE 文件。