CollectionModel
此 pod 的目标是提供一个数据结构来表示 collectionView/tableView 所显示的内容。它使您能够将任何业务逻辑从视图的 dataSource 中提取到负责生成其 viewModel 的代码部分。这有助于在应用程序中强制更好的关注点分离,并保持 dataSource 易于维护。
示例应用程序
要运行示例项目,请克隆仓库,然后从 Example 目录首先运行 bundle install & bundle exec pod install
。
使用方法
一切在 Xcode 中都有文档。
TableViewModel
TableViewModel
是一个结构体,尽可能地代表 UITableView
的结构。它是两个参数的泛型:HeaderFooterViewModel
和 CellViewModel
,这两个参数都很直观,它们应该代表用于配置 tableView 单元格或头部和尾部模型所使用的模型。
这个结构体主要是一个数组的包装器,该数组代表了 TableViewSectionViewModel
的数组,而 TableViewSectionViewModel
是一个结构体,代表 UITableView
的一个部分。
TableViewSectionViewModel
依赖于cellViewModels数组以及两个可空的标题和页脚属性。
如果您只使用一种类型的单元格,则基于tableViewModel实现tableViewDataSource相对简单。
class SimpleTableViewDataSource: NSObject,
UITableViewDataSource {
typealias ViewModel = TableViewModel<Never, ATableViewCellModel>
var viewModel = ViewModel()
func numberOfSections(in tableView: UITableView) -> Int {
viewModel.sections.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
viewModel[section].cells.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: ATableViewCell = tableView.dequeueCell(at: indexPath)
cell.configure(with: viewModel[indexPath])
return cell
}
}
如果必须使用多种类型的单元格,您应该为细胞类型创建一个枚举。
enum MultipleCellTypesTableViewCellModel {
case a(ATableViewCellModel)
case b(BTableViewCellModel)
}
这将只需要更改您对tableView(_:cellForRowAt:)
的实现,以管理细胞类型的情况。
有关更多详细信息,请参阅示例应用程序。
CollectionViewModel
CollectionViewModel
是一个结构体,它尽可能准确地表示UICollectionView
的结构。它是关于两个参数的泛型SupplementaryViewModel
和CellViewModel
,这两个参数都应该是自解释的,它们应该代表用于配置collectionView单元格或可能是标题、页脚或自定义补充视图的补充视图所使用的模型。
这个结构体主要是对CollectionSectionViewModel
数组的包装,这是一个结构体,代表UICollectionView
的一节。
CollectionSectionViewModel
依赖于一个cellViewModels数组以及一个存储着补充ViewModels的字典,其中键是SupplementaryViewSectionKey
,是一个索引和补充视图类型的配对。该节的标题和页脚存储在自己的变量中,独立于字典。
如果您只使用一种类型的单元格,基于CollectionViewModel
实现collectionViewDataSource相对简单。
class SimpleCollectionViewDataSource: NSObject,
UICollectionViewDataSource {
typealias ViewModel = CollectionViewModel<Never, CollectionViewCellModel>
var viewModel = ViewModel()
func numberOfSections(in collectionView: UICollectionView) -> Int {
viewModel.sections.count
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
viewModel[section].cells.count
}
func collectionView(_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell: ACollectionViewCell = collectionView.dequeueCell(at: indexPath)
cell.configure(with: viewModel.cellViewModel(at: indexPath))
return cell
}
}
如果必须使用多种类型的单元格,您应该为细胞类型创建一个枚举。
enum MultipleCellTypesCollectionViewCellModel {
case a(ACollectionViewCellModel)
case b(BCollectionViewCellModel)
}
这将只需要更改您对collectionView(_:cellForItemAt:)
的实现,以管理单元格类型的情况。
函数构建器
从CollectionModelCore 0.1.1(CollectionModel 0.2.1)起,您可以使用函数构建器提供的声明性语法创建viewModel。您可以使用两种不同的函数构建器来创建ViewModel或部分。
简单的声明式
您可以用声明式的方法创建一个部分或viewModel
Section {
cell1
if condition {
[
cell2,
cell3,
]
} else {
cell4
}
}
此实现支持if/else
语句,这意味着它也支持switch
。如示例所示,您可以从每一行返回一个单元格或单元格集合。但是,请注意,它支持任何单元格集合,因此请注意无序集合。
基于实体
由于当前无法在函数构建器中支持循环,因此提供了一个基于实体数组迭代的函数构建器。大多数情况下,您的实现将如下所示
Section(entities: entities) { entity in
cell1(for: entity)
}
但有时候您可能希望为单个实体返回多个单元,这也是可能的。
Section(entities: entities) { entity in
cell1(for: entity)
if condition {
[
cell2(for: entity),
cell3(for: entity),
]
} else {
cell(for: entity)
}
}
如您所见,此实现还支持if/else
语句并返回集合而不是单个元素。
需求
除了使用 Swift 之外,没有使用此 pod 的技术要求。
安装
CollectionModel 通过 CocoaPods 提供。要安装它,只需将以下行添加到您的 Podfile
pod 'CollectionModel'
作者
Denis Poifol,[email protected]
许可
CollectionModel 在 MIT 许可下可用。有关更多信息,请参阅 LICENSE 文件。