TableCollectionManager
TableCollectionManager
是一个轻量级的泛型库,允许您使用声明式、类型安全的风格来构建表格视图和集合视图。
-
类型安全的泛型单元格和模型
-
函数式编程风格
-
无需使用代理和数据源
-
模型自动更新视图
目录
安装
- 将以下内容添加到
Podfile
pod 'TableCollectionManager'
- 运行
pod install
。 - 添加到文件
import TableCollectionManager
使用
主要思想是你有一个管理器来管理表格/集合视图。并且这个管理器有存储,你可以更新其中的条目。然后发生魔法,视图会自动更新和重新加载。你还可以方便地以函数式风格处理操作。
TableView
表格快速上手
import TableCollectionManager
// create cell and implement TableConfigurable
class ExampleCell: UITableViewCell, TableConfigurable {
func update(with model: String) {
textLabel?.text = model
}
}
class VC: UIViewController {
// init manager
let manager = TableManager()
var tableView = UITableView(frame: .zero, style: .plain)
override func viewDidLoad() {
super.viewDidLoad()
// set tableView to manager
manager.tableView = tableView
// create rows
let firstRow = TableRow<ExampleCell>("First").didSelect { result in
// result.model - cell model
// result.cell - cell
// result.indexPath - indexPath
print("first")
}
let secondRow = TableRow<ExampleCell>("Second").didSelect { _ in
print("second")
}
// add rows to storage
manager.storage.append([firstRow, secondRow])
}
}
TableCell
要使用带有TableManager的单元格,您必须实现TableConfigurable
协议。
您需要实现update(with:)
函数以提供模型类型。
假设您有一个Pet
对象,您希望创建一个显示该项目数据的单元格。在这种情况下,单元格将如下所示。
struct Pet {
let name: String
let age: Int
}
class PetCell: UITableViewCell, TableConfigurable {
func update(with model: Pet) {
// fill cell with data
textLabel?.text = "\(model.name) is \(model.age) years old"
}
}
您还可以提供单元格的height
和estimatedHeight
。默认情况下,它们等于UITableView.automaticDimension
。
class Cell: UITableViewCell, TableConfigurable {
// custom height
static var height: CGFloat {
44
}
// custom estimatedHeight
static var estimatedHeight: CGFloat {
44
}
func update(with model: String) {
}
}
您也无需注册单元格。TableManager
会为您完成这一操作。
TableRow
TableRow
是单元格包装器。因此,您只需要为此行使用行和模型(viewModel)。
要创建 TableRow
,请提供单元格类型和模型实例。
let pet = Pet(name: "Elon", age: 2)
let petRow = TableRow<PetCell>(pet)
您还可以订阅来自 UITableViewDelegate/UITableViewDataSource
的某些操作。例如,您想要此行的 didSelect
。在这种情况下,只需调用 didSelect
。
petRow.didSelect { result in
// do something
// result.model - cell model
// result.cell - cell
// result.indexPath - indexPath
}
TableRow
支持以下操作
-
didSelect
-
didDeselect
-
willSelect
-
willDeselect
-
willDisplay
-
didEndDisplaying
-
moveTo
-
shouldHighlight
-
editingStyle
-
leadingSwipeActions
-
trailingSwipeActions
-
canEdit
-
canMove
-
commitStyle
-
move
您还可以链式调用操作。
let row = TableRow<Cell>(model).didSelect { _ in
print("selected")
}.willDisplay { _ in
print("willDisplay")
}.canEdit { _ in
return true
}
表头和页脚
表头和页脚几乎像单元格一样工作。唯一的区别是 estimatedHeight
是必需的。
class HeaderFooter: UITableViewHeaderFooterView, TableConfigurable {
// required
static var estimatedHeight: CGFloat {
44
}
// optional (UITableView.automaticDimension by default)
static var height: CGFloat {
44
}
func update(with model: String) {
textLabel?.text = model
}
}
TableHeaderFooter
是表头和页脚的包装器。要将它们添加到表格视图中,只需这样做。
let header = TableHeaderFooter<HeaderFooter>("Header")
// add header to section at index
manager.storage.setHeader(header, to: 0)
let footer = TableHeaderFooter<HeaderFooter>("Footer")
// add header to section at index
manager.storage.setFooter(footer, to: 1)
用户内容表格部分
用户内容表格部分
是 UITableView
部分的包装。如果你在表格视图中有很多部分,你应该使用 用户内容表格部分
。你可以为每个部分设置行、头和尾。
let rows = (1...10).map { TableRow<Cell>("\($0)") }
let header = TableHeaderFooter<HeaderFooter>("Header")
let footer = TableHeaderFooter<HeaderFooter>("Footer")
let section = TableSection(
rows: rows,
header: header,
footer: footer
)
manager.storage.append(section)
用户内容存储
用户内容存储
是一个存储所有部分和行的地方。每个TableManager
都有一个存储空间。如果您向这个存储表传递数据,视图将自动更新。
manager.storage.append(sections)
manager.storage.delete(row)
manager.storage.reload(rows)
// and ect.
您还可以获取部分索引、行indexPath、索引处的部分或indexPath处的行。
let sectionIndex = manager.storage.index(for: section)
let rowIndexPath = manager.storage.indexPath(for: row)
let section = manager.storage.section(at: index)
let row = manager.storage.row(at: indexPath)
存储有performWithoutAnimation
块。您在块内调用的每个更改都将无动画执行。
manager.storage.performWithoutAnimation {
manager.storage.append(sections)
manager.storage.reload(rows)
}
存储有performBatchUpdate
块。在您希望在一个单个动画操作中对多个更改的情况下,可以使用此方法。
manager.storage.performBatchUpdate({
manager.storage.append(sections)
manager.storage.delete(row)
}, completion: { isFinished in
// completion
})
所有存储功能
-
isEmpty
-
numberOfSections
-
numberOfAllRows
-
index(for section:<)
-
indexPath(for row:<)
-
section(at index:<)
-
row(at indexPath:<)
-
performWithoutAnimation(< block:)
-
performBatchUpdate(< block:, completion:)
-
reload()
-
reload(< row:)
-
reload(< rows:)
-
reload(< section:)
-
reload(< sections:)
-
append(< row:)
-
append(< rows:)
-
append(< row:, to sectionIndex:)
-
append(< rows:, to sectionIndex:)
-
append(< section:)
-
append(< sections:)
-
insert(< row:, at indexPath:)
-
insert(< section:, at index:)
-
delete(< row:)
-
delete(< rows:)
-
delete(< section:)
-
delete(< sections:)
-
deleteAllItems()
-
moveRowWithoutUpdate(from source:, to destination:)
-
moveRow(from source:, to destination:)
-
moveSection(from source:, to destination:)
TableManager
TableManager
是一个管理所有委托和数据源的对象。管理器包含 storage
和 tableView
。您可以更改这两个。
管理器还有一个 scrollHandler
,它处理 UIScrollViewDelegate
。
manager.scrollHandler.didScroll {
print("didScroll")
}.shouldScrollToTop {
return true
}
CollectionView
用户内容集合快速入门
import TableCollectionManager
// create cell and implement CollectionConfigurable
class ExampleCell: UICollectionViewCell, CollectionConfigurable {
func update(with model: String) {
textLabel?.text = model
}
}
class VC: UIViewController {
// init manager
let manager = CollectionManager()
var collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())
override func viewDidLoad() {
super.viewDidLoad()
// set collectionView to manager
manager.collectionView = collectionView
// create rows
let firstRow = CollectionRow<ExampleCell>("First").didSelect { result in
// result.model - cell model
// result.cell - cell
// result.indexPath - indexPath
print("first")
}
let secondRow = CollectionRow<ExampleCell>("Second").didSelect { _ in
print("second")
}
// add rows to storage
manager.storage.append([firstRow, secondRow])
}
}
CollectionCell
要使用与TableManager一起使用的单元格,您必须实现CollectionConfigurable
协议。
您需要实现update(with:)
函数以提供模型类型。
假设您有一个Pet
对象,您希望创建一个显示该项目数据的单元格。在这种情况下,单元格将如下所示。
struct Pet {
let name: String
let age: Int
}
class PetCell: UICollectionViewCell, CollectionConfigurable {
func update(with model: Pet) {
// fill cell with data
}
}
您还可以提供单元格的size
。这是可选的,您也可以使用UICollectionViewLayout
或使用CollectionManager的layoutHandler
来提供高度。
class Cell: UICollectionViewCell, CollectionConfigurable {
// custom size
static var size: CGSize? {
CGSize(width: 44, height: 44)
}
func update(with model: String) {
}
}
您也不需要注册单元格。CollectionManager
会为您完成这项任务。
CollectionRow
CollectionRow
是对单元格的包装。因此,您只与此行的行和模型(viewModel)一起工作。
要创建 CollectionRow
,请提供单元格类型和模型实例。
let pet = Pet(name: "Elon", age: 2)
let petRow = CollectionRow<PetCell>(pet)
您也可以订阅一些来自 UICollectionViewDelegate/UICollectionViewDataSource
的操作。例如,您想要对这个行的 didSelect
。在这种情况下,只需调用 didSelect
即可。
petRow.didSelect { result in
// do something
// result.model - cell model
// result.cell - cell
// result.indexPath - indexPath
}
CollectionRow
支持以下操作
-
didSelect
-
didDeselect
-
willDisplay
-
didEndDisplaying
-
moveTo
-
shouldHighlight
-
canMove
-
move
您还可以链式调用操作。
let row = CollectionRow<Cell>(model).didSelect { _ in
print("selected")
}.willDisplay { _ in
print("willDisplay")
}
CollectionHeaderFooter
页眉和页脚的工作方式几乎与单元格相同。大小处理方式与 CollectionRow
相同。
class HeaderFooter: UICollectionReusableView, CollectionConfigurable {
// custom size
static var size: CGSize? {
CGSize(width: 44, height: 44)
}
func update(with model: String) {
}
}
CollectionHeaderFooter
是页眉和页脚的包装器。您可以使用部分添加页眉/页脚。
let header = CollectionHeaderFooter<HeaderFooter>("Header")
let footer = CollectionHeaderFooter<HeaderFooter>("Footer")
let section = CollectionSection(
rows: [],
header: header,
footer: footer
)
收藏部分
收藏部分
是围绕UICollectioView
部分的包装。如果你的表格视图中有多于一个部分,你应该使用收藏部分
。你可以为每个部分设置行、标题和底部。
let rows = (1...10).map { CollectioRow<Cell>("\($0)") }
let header = CollectionHeaderFooter<HeaderFooter>("Header")
let footer = CollectionHeaderFooter<HeaderFooter>("Footer")
let section = CollectionSection(
rows: rows,
header: header,
footer: footer
)
manager.storage.append(section)
CollectionStorage
CollectionStorage
是所有部分和行存储的地方。每个CollectionManager
都有一个存储空间。如果将数据传递到这个存储空间,视图将自动更新。
manager.storage.append(sections)
manager.storage.delete(row)
manager.storage.reload(rows)
// and ect.
您还可以获取部分索引、行indexPath、索引处的部分或indexPath处的行。
let sectionIndex = manager.storage.index(for: section)
let rowIndexPath = manager.storage.indexPath(for: row)
let section = manager.storage.section(at: index)
let row = manager.storage.row(at: indexPath)
存储有performWithoutAnimation
块。您在块内调用的每个更改都将无动画执行。
manager.storage.performWithoutAnimation {
manager.storage.append(sections)
manager.storage.reload(rows)
}
存储有performBatchUpdate
块。在您希望在一个单个动画操作中对多个更改的情况下,可以使用此方法。
manager.storage.performBatchUpdate({
manager.storage.append(sections)
manager.storage.delete(row)
}, completion: { isFinished in
// completion
})
所有存储功能与TableStorage
相同。
集合管理器
集合管理器
是一个管理所有代理和数据源的物体。管理器包含存储
和集合视图
。您可以更改它们两个。
管理器还有一个 scrollHandler
,它处理 UIScrollViewDelegate
。
manager.scrollHandler.didScroll {
print("didScroll")
}.shouldScrollToTop {
return true
}
管理器还有布局处理
,可以处理UICollectionViewDelegateFlowLayout
和collectionView(_ :transitionLayoutForOldLayout:newLayout:)
代理方法。
例如,您可以提供项的大小。
manager.layoutHandler.sizeForItem { indexPath in
return CGSize(width: 44, height: 44)
}.sizeForHeader { sectionIndex in
return CGSize(width: 44, height: 44)
}
许可证
TableCollectionManager 采用 MIT 许可证。有关更多信息,请参阅 LICENSE
文件。