列出项目(入门)
设想要将一组项目放入简单的列表中并展示,而不需要创建表格视图子类并进入代理和数据源。
1. 模型
let models = ["Apple", "Microsoft", "Google"]
2. 描述Cell for model
描述单对model的cell会做什么。
let cellDescs = models.map { m -> ListCellDescriptor<String, SimpleCell> in
var cd = ListCellDescriptor(m, identifier: identifier, cellClass: SimpleCell.self,
// 1. Configure
configure: { cell in
cell.textLabel?.text = m
})
// set action handler
cd.onSelect = { [weak self] in
self?.tapped(m)
}
return cd
}
上面使用的SimpleCell仅仅是正常UITableViewCell的空子类。建议子类化并提供符合您业务逻辑的定制设计。
class SimpleCell: UITableViewCell { }
3. 打包到SectionDescriptors
SectionDescriptors仅仅是分组CellDescriptors的一种方式。可以将它们视为每个部分cell视图模型数组的集合。
/// A SectionDescriptor is made up of array of cell descriptor.
let sections = ListSectionDescriptor(with: cellDescs)
4. 构建设计ListViewController
/// A List is made of up array of section.
let list = ListViewController(with: [sections])
5. 高效更新
如果你的模型在列表已经显示之后更新,只需将新的sectionDescriptors
传递给列表的update
方法。
list.update(with: newSections)
ListViewController
使用了FastDiff
,这是一种时间复杂度为O(nm)的非常快速的diffing算法,可以执行标准表格视图动画的更新。
6. 出现
就这样。
注意
到目前为止,我们已看到如何使用单个类型的单元格开发单一类型/变体的模型。我们甚至只有一个部分。这被称为同构类型的列表。
我们能支持多个部分吗?
高级(异构列表)
首先,这是如何建模列表的。
List == [SectionDescriptor<T>] // 1
SectionDescriptor<T> == [CellDescriptor<T,U>] where U: UITableViewCell // 2
使用这种方法
- 列表可以有相同类型的部分
- 每个部分可以有相同类型的单元格
T
类型是模型类型。由于我们可以推断出U是UITableViewCell的子类,因此它被省略在部分中以提高简洁性。
因此,我们可以尝试将模型类型T
擦除为AnyHashable
,以便能够构造异构列表。库通过在ListCellDescriptor
和SectionCellDescriptor
上公开any()
函数,使这变得非常简单和安全。
1. 使用第二部分开发新模型
struct ModelItem: Hashable {
let color: UIColor
let int: Int
}
let modelsForNextSection = [ModelItem(color: .red, int: 1), .init(color: .blue, int: 2), .init(color: .purple, int: 3)]
2. 像之前一样构造CellDescription
let cellDescs2 = modelsForNextSection.map { m in
return ListCellDescriptor(m, identifier: identifier2, cellClass: SimpleCell.self, configure: { cell in
cell.textLabel?.text = "\(m.int)"
cell.backgroundColor = m.color // setting color for the cell
})
}
let secondSection = ListSectionDescriptor(with: cellDescs2)
3. 合并两个不同的部分
给定ListSectionDescriptor
和ListSectionDescriptor
,我们需要将它们打包到一个单数组的。为此,我们清除模型类型。
/// note the .any()
let combinedSections = [sections.any(), secondSection.any()]
let list = ListViewController(with: combinedSections)
注意
使用这种方法,可以结合任何种类的cellDescriptor和sectionDescriptor,而无需在声明特定模型时引入类型擦除或转型。
参见图片查看异构列表
高级(带有部分混合单元的异构列表)
1. 带有不同的模型和单元的部分
假设我们想在同一个部分中使用SimpleCell和AnotherCell表示Int和String类型的模型。
class AnotherCell: UITableViewCell { }
let mc1 = ListCellDescriptor(1, identifier: "mc1", cellClass: SimpleCell.self, configure: { cell in
cell.textLabel?.text = "\(1)"
})
/// look out for cell identifier
let mc2 = ListCellDescriptor("hello", identifier: "mc2", cellClass: AnotherCell.self, configure: { cell in
cell.textLabel?.text = "hello"
cell.backgroundColor = .purple
})
2. 构造sectionDescriptor
由于我们希望在部分中存放多种类型的模型,因此我们的部分需要是类型擦除的。
/// .any() on ListCellDescriptor
let mixedSection = ListSectionDescriptor(with: [mc1.any(), mc2.any()])
3. 展示
只需将其附加到我们之前构建的2个示例之上并显示即可。
let combinedSections = [sections.any(), secondSection.any(), mixedSection]
let list = ListViewController(with: combinedSections)
注意
现在,如果我们选择,我们可以拥有完整的异构列表功能。
高级(自定义操作处理)
待定
什么是这个“点”?
这是一个小巧的库,它可以消除我们对每个我们想要显示的简单列表的基本和重复的UITableView子类封装、代理和数据处理。它还提供了开箱即用的有效更新。为什么不尽情地声明要制作的列表,然后欣赏它。
这绝对不是一个广泛列表的库,对于这个,始终使用UITableView或UICollectionView。这在需要抛入一个列表用于展示、原型或简单的只读列表时非常有用。