UITableViewDelegate 不适用于 UITableViewDiffableDataSource



我创建了一个测试项目来重现这个问题https://github.com/msnazarow/DiffarableTest

你只需要通过几个步骤

  1. 创建新目标
  2. 创建继承UITableViewDiffableDataSourceUITableViewDelegate但不实现UITableViewDelegate方法的Base
  3. 在另一个目标(主要为简化)继承Base类和实现任何UITableViewDelegate方法(例如didSelectRowAt)
  4. 所有的实现方法都不起作用

您必须在BaseDataSource类中配置委托函数,以便在子类中被覆盖。

因此,第一步,在extension MyDataSource: 中注释掉didSelectRowAt函数
extension MyDataSource {
//  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//      print("CELL SELECTED")
//  }
}

和实现didSelectRowAtBaseDataSource:

open class BaseDataSource<T: Model & Hashable>: UITableViewDiffableDataSource<Int, T>, UITableViewDelegate {
public init(tableView: UITableView) {
super.init(tableView: tableView) { tableView, indexPath, model in
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) as! Configurable
cell.configure(with: model)
return cell as? UITableViewCell
}
}
public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("Base Cell Selected", indexPath)
}
}

当你运行应用程序并点击第三行时,你应该得到调试输出:

Base Cell Selected [0, 2]

要在子类中实现它,你可以重写它:

extension MyDataSource {
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("MyDataSource Cell Selected", indexPath)
}
}
不能覆盖来自扩展的非动态类声明…所以在BaseDataSource: 中设置为动态
open class BaseDataSource<T: Model & Hashable>: UITableViewDiffableDataSource<Int, T>, UITableViewDelegate {
public init(tableView: UITableView) {
super.init(tableView: tableView) { tableView, indexPath, model in
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath) as! Configurable
cell.configure(with: model)
return cell as? UITableViewCell
}
}
public dynamic func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("Base Cell Selected", indexPath)
}
}

点击第三行现在应该输出:

MyDataSource Cell Selected [0, 2]

注意如果没有子类化委托,BaseDataSource中的didSelectRowAt将被调用。另外,如果你想要一些代码BaseDataSource中运行didSelectRowAt,您可以从子类调用super:

extension MyDataSource {
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
super.tableView(tableView, didSelectRowAt: indexPath)
print("MyDataSource Cell Selected", indexPath)
}
}

和选择第三行输出:

Base Cell Selected [0, 2]
MyDataSource Cell Selected [0, 2]

编辑

经过更多的研究,这被一些人认为是一个"bug"。

然而,一个很大的变化是Swift最初做的,但不再,推断@objc。当需要将@objc添加到函数(例如在选择器中使用时)时,每个人都遇到过这种情况。

那么,有两种方法来处理这个…

首先,如上所示,实现"什么都不做";

在子类中重写任何表视图委托函数。 第二个选项,听起来像是您更喜欢的,是在子类(或其扩展)中声明@objc方法:
extension MyDataSource {
// add this line
@objc (tableView:didSelectRowAtIndexPath:)
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("MyDataSource extension Cell Selected", indexPath)
}
}

现在你可以回到你的原始代码,你只需要添加一行来获得所需的功能。

相关内容

  • 没有找到相关文章

最新更新