UITableView
简化了!
主要功能 | |
---|---|
跳过 UITableViewDataSource 和 UITableViewDelegate 的样板代码,直接构建您的 UITableView ! |
|
基于闭包的 API 用于分区和行配置 | |
内建分页功能 | |
单元测试 | |
使用 Swift 5.0 编写 |
TableViewLiaison
是
需求
- Xcode 10.2+
- iOS 10.0+
安装
CocoaPods
首选安装方法是使用 CocoaPods。将以下内容添加到您的 Podfile 中
pod 'TableViewLiaison'
示例
要运行示例项目,首先克隆仓库,然后在 Example 目录中运行 pod install
。
使用方法
TableViewLiaison
允许您更轻松地填充和处理 UITableView
的行和部分。
入门
要开始使用,您只需要将一个实例的 UITableView
与一个 TableViewLiaison
进行连接。
let liaison = TableViewLiaison()
let tableView = UITableView()
liaison.liaise(tableView: tableView)
通过将您的 UITableView
连接到 TableViewLiaison
,TableViewLiaison
成为它的 UITableViewDataSource
、UITableViewDelegate
和 UITableViewDataSourcePrefetching
。如果您想从 TableViewLiaison
中移除 UITableView
,只需调用 liaison.detach()
。
TableViewLiaison
实现了多个辅助方法来帮助您管理 UITableView
。
TableViewLiaison
使用两种主要类型填充部分和行。
部分
struct TableViewSection
为了为我们的 UITableView
创建部分,创建一个 TableViewSection
的实例并将其添加到 TableViewLiaison
中。
let one = TableViewSection()
let two = TableViewSection(id: "ID")
let liaison = TableViewLiaison(sections: [one, two])
或者
let section = TableViewSection()
liaison.append(section: section)
补充部分的视图
为了通知 TableViewLiaison
您的 TableViewSection
将显示头部和/或尾部视图,您必须在初始化期间提供一个 TableViewSectionComponentDisplayOption
实例。
TableViewSectionComponentDisplayOption
是一个枚举,告诉联络器为给定的部分应显示哪些辅助视图。头部/尾部视图由
class TableViewSectionComponent<View: UITableViewHeaderFooterView>
let header = TableViewSectionComponent<UITableViewHeaderFooterView>()
let section = TableViewSection(option: .header(component: header))
您可以通过使用 CGFloat 值或闭包来设置 TableViewSectionComponent
的静态高度
header.set(.height, 55)
header.set(.height) {
// Some arbitrary user you pass into the closure...
return user.username == "dylan" ? 100 : 75
}
header.set(.estimatedHeight, 125)
如果未为 TableViewSectionComponent
提供高度,TableViewLiaison
会假定辅助视图是自动大小的,并返回 .height
为 UITableView.automaticDimension
。请确保您提供 .estimatedHeight
以避免布局问题。
可以使用 set(_ command: TableViewSectionComponentCommand, with closure: @escaping (View, Int) -> Void)
在所有以下的生命周期事件中对 TableViewSectionComponent
视图进行自定义
- 配置
- didEndDisplaying
- willDisplay
header.set(.configuration) { view, section in
view.textLabel?.text = "Section \(section)"
}
header.set(.willDisplay) { view, section in
print("Header: \(view) will display for Section: \(section)")
}
行
class TableViewRow>Cell: UITableViewCell, Data
要为某个部分添加行,请创建 TableViewRow
的实例并将其传递给 TableViewSection
的初始化器。如果行在实例化后添加,则可以通过 TableViewLiaison
执行该操作。
let row = TableViewRow<RowTableViewCell, Int>(data: 1)
let statelessRow = StatelessTableViewRow<RowTableViewCell>()
let section = TableViewSection(rows: [row, statelessRow])
liaison.append(section: section)
或者
let row = TableViewRow()
let section = TableViewSection()
liaison.append(section: section)
liaison.append(row: row)
TableViewRow
的高度配置类似于 TableViewSection
。
row.set(.height, 300)
row.set(.estimatedHeight, 210)
row.set(.height) { data in
switch data.type {
case .large:
return 400
case .medium:
return 200
case .small:
return 50
}
}
如果未提供高度,则 TableViewLiaison
假设单元格是自动大小的,并返回 UITableView.automaticDimension
。
可以使用 func set(_ command: TableViewRowCommand, with closure: @escaping (TableViewLiaison, Cell, Data, IndexPath) -> Void)
在以下所有生命周期事件中自定义 TableViewRow
- accessoryButtonTapped
- 配置
- delete
- didDeselect
- didEndDisplaying
- didEndEditing
- didHighlight
- didSelect
- didUnhighlight
- insert
- move
- reload
- willBeginEditing
- willDeselect
- willDisplay
- willSelect
row.set(.configuration) { liaison, cell, data, indexPath in
cell.label.text = "Cell: \(cell) at IndexPath: \(indexPath) with \(data)"
cell.label.font = .systemFont(ofSize: 13)
cell.contentView.backgroundColor = .blue
cell.selectionStyle = .none
}
row.set(.didSelect) { liaison, cell, data, indexPath in
print("Cell: \(cell) selected at IndexPath: \(indexPath) with \(data)")
}
TableViewRow
还可以通过 func set(prefetchCommand: TableViewPrefetchCommand, with closure: @escaping (IndexPath) -> Void)
使用 UITableViewDataSourcePrefetching
row.set(.prefetch) { cellViewModel, indexPath in
cellViewModel.downloadImage()
}
row.set(.cancel) { cellViewModel, indexPath in
cellViewModel.cancelImageDownload()
}
单元格/视图注册
TableViewLiaison
利用你的部分/行 TableViewRegistrationType<T>
代理为你处理单元格和视图的注册,以便在你的 UITableView
视图重用方面。
TableViewRegistrationType
通知代理是否应通过 Nib
或 Class
注册可重用的视图。
默认情况下,TableViewRow
使用 TableViewRegistrationType<Cell>.defaultClassType
实例化。
TableViewSection
补充视图注册被封装在其 TableViewSectionComponentDisplayOption
中。默认情况下,TableViewSection
选项使用 .none
实例化。
分页
TableViewLiaison
搭载了处理分页需求的工具。要为分页配置代理,只需将它的 paginationDelegate
设置为 TableViewLiaisonPaginationDelegate
的实例。
TableViewLiaisonPaginationDelegate
声明三个方法
func isPaginationEnabled() -> Bool
,通知代理是否在用户滚动到最后一行后显示分页指示器。
func paginationStarted(indexPath: IndexPath)
,传递经过联络者管理的最后一个TableViewRow
的indexPath。
func paginationEnded(indexPath: IndexPath)
,传递联络者附加的第一个新的TableViewRow
的indexPath。
为了在分页期间更新联络者的结果,简单地使用append(sections: [AnyTableViewSection])
或func append(rows: [AnyTableViewRow])
,然后联络者将自动处理分页加载器的移除。
要使用自定义的分页加载器,你可以在初始化你的TableViewLiaison
时传递一个AnyTableViewRow
实例。默认情况下,它使用框架提供的PaginationTableViewRow
。
技巧与窍门
由于TableViewSection
和TableViewRow
使用了泛型类型并管理视图/单元格类型的注册,创建多个不同的配置的章节和行可能会变得冗长。利用类型别名和/或实现静态工厂可能是有用的。
public typealias ImageRow= TableViewRow<ImageTableViewCell, UIImage>
static func imageRow(with image: UIImage) -> AnyTableViewRow {
let row = ImageRow(data: image)
row.set(.height, 225)
row.set(.configuration) { liaison, cell, image, indexPath in
cell.contentImageView.image = image
cell.contentImageView.contentMode = .scaleAspectFill
}
return row
}
贡献
TableViewLiaison
处于初期阶段。它的实现还不够完美。并不是所有的UITableView
功能都被liaised
。如果你想帮助将TableViewLiaison
带到更佳之地,请随意提交拉取请求。
作者
授权协议
TableViewLiaison在MIT授权协议下可用。有关更多信息,请参阅LICENSE文件。