首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UITableViewDelegate不适用于UITableViewDiffableDataSource

UITableViewDelegate不适用于UITableViewDiffableDataSource
EN

Stack Overflow用户
提问于 2022-06-22 19:12:41
回答 1查看 91关注 0票数 -2

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

只是你需要通过几个步骤

didSelectRowAt)

  • None

  • 创建新的目标

  • 创建继承UITableViewDiffableDataSourceUITableViewDelegateBase类,但在另一个目标(主要用于简化)继承Base类并实现UITableViewDelegate方法(例如,实现方法的UITableViewDelegate方法的Base>H 216G 217)中的<UITableViewDiffableDataSource>H 110不实现UITableViewDelegate方法(主要用于简化)。
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-06-22 20:52:20

您必须将BaseDataSource类中的委托函数配置为在子类中被重写。

因此,第一步,在extension MyDataSource中注释掉您的extension MyDataSource功能。

代码语言:javascript
复制
extension MyDataSource {
//  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//      print("CELL SELECTED")
//  }
}

并在didSelectRowAt中实现BaseDataSource

代码语言:javascript
复制
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)
    }
}

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

代码语言:javascript
复制
Base Cell Selected [0, 2]

要在子类中实现这一点,可以重写它:

代码语言:javascript
复制
extension MyDataSource {
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("MyDataSource Cell Selected", indexPath)
    }
}

您将得到一个错误:无法覆盖来自扩展的非动态类声明.所以让它在BaseDataSource中是动态的

代码语言:javascript
复制
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)
    }
}

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

代码语言:javascript
复制
MyDataSource Cell Selected [0, 2]

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

代码语言:javascript
复制
extension MyDataSource {
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        super.tableView(tableView, didSelectRowAt: indexPath)
        print("MyDataSource Cell Selected", indexPath)
    }
}

并选择第3行输出:

代码语言:javascript
复制
Base Cell Selected [0, 2]
MyDataSource Cell Selected [0, 2]

编辑

经过进一步的研究,一些人认为这是一个"bug“,因为它似乎在Swift版本之间发生了变化。

然而,在此过程中,斯威夫特的一个重大变化是,斯威夫特最初做了,但现在没有了,推断出当有必要在函数中添加@objc时,每个人都会遇到这种情况,比如在选择器中使用时。

有两种方法来处理这件事..。

首先,如上面所示,对您想要在子类中重写的任何表视图委托函数实现“什么都不做”函数。

第二个选项(听起来像是您喜欢的)是在您的子类(或它的扩展)中声明@objc方法:

代码语言:javascript
复制
extension MyDataSource {
    // add this line
    @objc (tableView:didSelectRowAtIndexPath:)

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

现在,您可以返回原始代码,只需添加一行即可获得所需的功能。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72720854

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档