在两个不同的类中实现UITableViewDataSource协议

Guy*_*her 6 protocols uitableview ios swift swift-protocols

我不确定这可以做到,或者甚至不推荐.

我想要实现的目标如下:

我有一个2类,classA并且classB引用了同一个UITableview实例.我想要的是负责协议classA的2个必要方法的实现UITableViewDataSource:

  • numberOfRowsInSection
  • cellForRowAt

然后我希望classB能够实现其他可选方法titleForHeaderInSection,例如.

那么如何才能classA有一些协议方法的默认实现,让我们classB成为一个可以在classB已经完成的基础上构建的类?

在某种程度上,我面临的问题如下:多个类如何成为单个数据源UITableView

编辑: classA将在我正在编写的库中,负责构建tableView的核心部分.classB将由第三方开发人员用于主要定制其外观.

Sul*_*han 5

我认为不手动重定向所有内容的唯一解决方案是使用协议方法的默认实现,例如:

protocol MyTableViewProtocol : UITableViewDelegate, UITableViewDataSource {

}

extension MyTableViewProtocol {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 5
    }
}
Run Code Online (Sandbox Code Playgroud)

然后 makeClassB来实现MyTableViewProtocol而不是UITableViewDelegateand UITableViewDataSource

但是,这样的解决方案将不起作用,因为 Obj-C 无法访问协议扩展。

我认为一个更干净(和工作)的解决方案是在协议之外创建实现,numberOfRowsInSectioncellForRowAtClassB他们在委托方法内调用它们,例如:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return MyTable.tableView(tableView: tableView, numberOfRowsInSection: section)
}
Run Code Online (Sandbox Code Playgroud)

这样的解决方案对用户来说会更清晰,因为它包含的“魔法”更少。

当然,经典的解决方案是定义自己的委托:

protocol MyTableViewProtocol {
    func myTableView(_ tableView: MyTableView, ...)   
    ...    
}
Run Code Online (Sandbox Code Playgroud)

并将所有内容从您的委托重定向到它。

此解决方案使您无法ClassB覆盖您不希望它覆盖的委托函数。