CollectionModel
此 pod 的目标是为collectionView/tableView显示的内容提供一个数据结构。它允许将任何业务逻辑从视图的数据源提取到负责生成其viewModel的代码部分。这有助于在您的应用中强制更好的关注点分离,并使dataSources易于维护。
示例应用
要运行示例项目,请首先从仓库中克隆项目,然后从Example目录中运行bundle install & bundle exec pod install
使用方法
所有内容在 Xcode 中均有文档说明。
TableViewModel
TableViewModel
是一个结构体,尽可能紧密地表示 UITableView
的结构。它对两个参数进行泛型化 HeaderFooterViewModel
和 CellViewModel
这两个参数显然可以解释,它们应该代表用于配置tableView单元格或头部和尾部的模型。
该结构主要是一个对TableViewSectionViewModel
数组的封装,其中TableViewSectionViewModel
是一个表示UITableView
中一个分区的结构。
TableViewSectionViewModel
依赖于一个cellViewModels数组以及两个可空的header和footer属性。
如果你的表格只使用一种类型的cell,基于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
}
}
如果需要使用多种类型的cell,你应该为你的cell类型创建一个枚举。
enum MultipleCellTypesTableViewCellModel {
case a(ATableViewCellModel)
case b(BTableViewCellModel)
}
这将要求你只更改tableView(_:cellForRowAt:)
的实现,以便管理cell类型的各种情况。
更多细节,请参阅示例应用程序。
CollectionViewModel
CollectionViewModel
尽可能表示一个UICollectionView
的结构。它是两个参数的泛型结构,即SupplementaryViewModel
和CellViewModel
,这两个参数都是不言自明的,它们应该代表配置collectionView的cell或补充视图(可以是header、footer或自定义补充视图)所使用的模型。
该结构主要是一个对CollectionSectionViewModel
数组的封装,其中CollectionSectionViewModel
是一个表示UICollectionView
一个分区的结构。
CollectionSectionViewModel
依赖于一个cellViewModels数组和一个存储supplementaryViewModels的字典,其中的键是SupplementaryViewSectionKey
,它是一对索引和补充视图类型的关键字。该节的header和footer存储在字典之外的自变量中。
如果你的collectionView只使用一种类型的cell,基于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
}
}
如果需要使用多种类型的cell,你应该为你的cell类型创建一个枚举。
enum MultipleCellTypesCollectionViewCellModel {
case a(ACollectionViewCellModel)
case b(BCollectionViewCellModel)
}
这将要求你只更改collectionView(_:cellForItemAt:)
的实现,以便管理cell类型的各种情况。
函数构建器
自从CollectionModelCore 0.1.1(CollectionModel 0.2.1)以来,您可以使用函数构建器提供的声明性语法创建viewModel。您可以使用两种不同的函数构建器来创建ViewModel或部分(section)。
简单的声明性语法
您可以使用声明性方式创建部分(section)或viewModel。
Section {
cell1
if condition {
[
cell2,
cell3,
]
} else {
cell4
}
}
本实现支持if/else
语句,这意味着它也支持switch
。从示例中您可以看到,您可以选择一行返回一个单元格或单元格集合。但请小心,它支持任何单元格集合,所以要注意无序集合。
基于实体
由于目前无法在函数构建器中支持for循环,因此提供了一个基于实体数组迭代的函数构建器。大多数情况下,您的实现看起来会是这样
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文件。