UITableViewDiffableDataSource:如何设置部分 header 标题?
UITableViewDiffableDataSource: how to set section header titles?
我正在尝试在 UITableViewController
.
中使用新的 UITableViewDiffableDataSource
设置一个 UITableView
部分
除了设置部分 header 标题外,一切似乎都正常。
根据 Apple 的文档,UITableViewDiffableDataSource
符合 UITableViewDataSource
,所以我希望这是可能的。
我试过:
- 覆盖 tableView(_ tableView:, titleForHeaderInSection section:)
在 UITableViewController class
- subclassing UITableViewDiffableDataSource 并在 subclass
中实现 tableView(_ tableView:, titleForHeaderInSection section:)
但这两种方式都没有结果(Xcode 11 和 iOS13 beta 3)。
目前是否可以使用 UITableViewDiffableDataSource
设置 header 部分的标题?
更新:从 beta 8 开始,您现在可以在 UITableViewDiffableDataSource 子类中实现 tableView(_ tableView:, titleForHeaderInSection section:)
,它可以正常工作。
填充 header 标题的默认行为在数据源中一直有点奇怪。对于 UITableViewDiffableDataSource,Apple 似乎通过不提供默认 string-based 行为来承认这一点;但是,UITableViewDelegate 方法继续像以前一样工作。通过初始化并返回具有所需部分标题的 UILabel 并实施 tableView(_:heightForHeaderInSection:)
来管理所需的高度来实施 tableView(_:viewForHeaderInSection:)
。
提供关于@particleman 解释的代码示例。
struct User: Hashable {
var name: String
}
enum UserSection: String {
case platinum = "Platinum Tier"
case gold = "Gold Tier"
case silver = "Silver Tier"
}
class UserTableViewDiffibleDataSource: UITableViewDiffableDataSource<UserSection, User> {
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
guard let user = self.itemIdentifier(for: IndexPath(item: 0, section: section)) else { return nil }
return self.snapshot().sectionIdentifier(containingItem: user)?.rawValue
}
}
将 self.dataSource
初始化为 UITableViewDiffableDataSource
(将其自身设置为 tableView.dataSource
)后,将 tableView.dataSource
设置回自身,即 UITableViewController
子class。现在在你的 numberOfSectionsInTableView
和 numberOfRowsInSection
方法中将它们转发给 self.dataSource
和 return 它的信息(这是组合模式)。现在您的 UITableViewController
只是正常实现其部分标题,因为它是 table 的数据源。
我认为 UITableViewDiffableDataSource
不应该将自己设置为数据源,如果已经设置的话,但我猜他们将其设计为以最不容易出错的方式工作,因为将 UITableViewController
添加到故事板已经设置好了。
如果你这样做,那么 class 在早期的 iOS 13 个测试版中没有开放的原因是有道理的。
让我提出一个非常灵活的通用解决方案:
声明一个子类:
class StringConvertibleSectionTableViewDiffibleDataSource<UserSection: Hashable, User: Hashable>: UITableViewDiffableDataSource<UserSection, User> where UserSection: CustomStringConvertible {
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sectionIdentifier(for: section)?.description
}
}
用法示例:
class ComitsListViewController: UITableViewController {
private var diffableDataSource = StringConvertibleSectionTableViewDiffibleDataSource<String, Commit>(tableView: tableView) { (tableView, indexPath, commit) -> UITableViewCell? in
let cell = tableView.dequeueReusableCell(withIdentifier: "Commit", for: indexPath)
cell.configure(with: commit)
return cell
}
}
你不仅仅局限于String
思想。您可以通过为您的部分类型实施 description
var of CustomStringConvertible
协议来控制显示为部分标题的内容。
我正在尝试在 UITableViewController
.
UITableViewDiffableDataSource
设置一个 UITableView
部分
除了设置部分 header 标题外,一切似乎都正常。
根据 Apple 的文档,UITableViewDiffableDataSource
符合 UITableViewDataSource
,所以我希望这是可能的。
我试过:
- 覆盖 tableView(_ tableView:, titleForHeaderInSection section:) 在 UITableViewController class
- subclassing UITableViewDiffableDataSource 并在 subclass 中实现 tableView(_ tableView:, titleForHeaderInSection section:)
但这两种方式都没有结果(Xcode 11 和 iOS13 beta 3)。
目前是否可以使用 UITableViewDiffableDataSource
设置 header 部分的标题?
更新:从 beta 8 开始,您现在可以在 UITableViewDiffableDataSource 子类中实现 tableView(_ tableView:, titleForHeaderInSection section:)
,它可以正常工作。
填充 header 标题的默认行为在数据源中一直有点奇怪。对于 UITableViewDiffableDataSource,Apple 似乎通过不提供默认 string-based 行为来承认这一点;但是,UITableViewDelegate 方法继续像以前一样工作。通过初始化并返回具有所需部分标题的 UILabel 并实施 tableView(_:heightForHeaderInSection:)
来管理所需的高度来实施 tableView(_:viewForHeaderInSection:)
。
提供关于@particleman 解释的代码示例。
struct User: Hashable {
var name: String
}
enum UserSection: String {
case platinum = "Platinum Tier"
case gold = "Gold Tier"
case silver = "Silver Tier"
}
class UserTableViewDiffibleDataSource: UITableViewDiffableDataSource<UserSection, User> {
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
guard let user = self.itemIdentifier(for: IndexPath(item: 0, section: section)) else { return nil }
return self.snapshot().sectionIdentifier(containingItem: user)?.rawValue
}
}
将 self.dataSource
初始化为 UITableViewDiffableDataSource
(将其自身设置为 tableView.dataSource
)后,将 tableView.dataSource
设置回自身,即 UITableViewController
子class。现在在你的 numberOfSectionsInTableView
和 numberOfRowsInSection
方法中将它们转发给 self.dataSource
和 return 它的信息(这是组合模式)。现在您的 UITableViewController
只是正常实现其部分标题,因为它是 table 的数据源。
我认为 UITableViewDiffableDataSource
不应该将自己设置为数据源,如果已经设置的话,但我猜他们将其设计为以最不容易出错的方式工作,因为将 UITableViewController
添加到故事板已经设置好了。
如果你这样做,那么 class 在早期的 iOS 13 个测试版中没有开放的原因是有道理的。
让我提出一个非常灵活的通用解决方案:
声明一个子类:
class StringConvertibleSectionTableViewDiffibleDataSource<UserSection: Hashable, User: Hashable>: UITableViewDiffableDataSource<UserSection, User> where UserSection: CustomStringConvertible {
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sectionIdentifier(for: section)?.description
}
}
用法示例:
class ComitsListViewController: UITableViewController {
private var diffableDataSource = StringConvertibleSectionTableViewDiffibleDataSource<String, Commit>(tableView: tableView) { (tableView, indexPath, commit) -> UITableViewCell? in
let cell = tableView.dequeueReusableCell(withIdentifier: "Commit", for: indexPath)
cell.configure(with: commit)
return cell
}
}
你不仅仅局限于String
思想。您可以通过为您的部分类型实施 description
var of CustomStringConvertible
协议来控制显示为部分标题的内容。