我创建了测试项目来再现问题https://github.com/msnazarow/DiffarableTest。
只是你需要通过几个步骤
didSelectRowAt)
UITableViewDiffableDataSource和UITableViewDelegate的Base类,但在另一个目标(主要用于简化)继承Base类并实现UITableViewDelegate方法(例如,实现方法的UITableViewDelegate方法的Base>H 216G 217)中的<UITableViewDiffableDataSource>H 110不实现UITableViewDelegate方法(主要用于简化)。发布于 2022-06-22 20:52:20
您必须将BaseDataSource类中的委托函数配置为在子类中被重写。
因此,第一步,在extension MyDataSource中注释掉您的extension MyDataSource功能。
extension MyDataSource {
// func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// print("CELL SELECTED")
// }
}并在didSelectRowAt中实现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 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中的BaseDataSource。此外,如果您想要的一些代码也可以在didSelectRowAt中运行的BaseDataSource中运行,您可以从子类调用super:
extension MyDataSource {
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
super.tableView(tableView, didSelectRowAt: indexPath)
print("MyDataSource Cell Selected", indexPath)
}
}并选择第3行输出:
Base Cell Selected [0, 2]
MyDataSource Cell Selected [0, 2]编辑
经过进一步的研究,一些人认为这是一个"bug“,因为它似乎在Swift版本之间发生了变化。
然而,在此过程中,斯威夫特的一个重大变化是,斯威夫特最初做了,但现在没有了,推断出当有必要在函数中添加@objc时,每个人都会遇到这种情况,比如在选择器中使用时。
有两种方法来处理这件事..。
首先,如上面所示,对您想要在子类中重写的任何表视图委托函数实现“什么都不做”函数。
第二个选项(听起来像是您喜欢的)是在您的子类(或它的扩展)中声明@objc方法:
extension MyDataSource {
// add this line
@objc (tableView:didSelectRowAtIndexPath:)
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("MyDataSource extension Cell Selected", indexPath)
}
}现在,您可以返回原始代码,只需添加一行即可获得所需的功能。
https://stackoverflow.com/questions/72720854
复制相似问题