请考虑通过
Cocoapods包含的模块中的以下代码(我使用Eureka,但问题不应与此相关):
open class FormViewController : UIViewController { } extension FormViewController : UITableViewDelegate { func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell { // some default implementation } /// some other UITableViewDelegate methods follow,but _NOT_ willDisplayCell }
我试图继承FormViewController并为tableView添加一个实现(_:willDisplay:forRowAt :)(这是UITableViewDelegate的可选方法).此方法在原始FormViewController中没有实现:
import UIKit import Eureka class MyViewController: FormViewController { override func viewDidLoad() { let tableView = UITableView(frame: self.view.bounds,style: .grouped) tableView.delegate = self tableView.dataSource = self self.tableView = tableView self.view.addSubview(self.tableView!) super.viewDidLoad() form = Form() let section = Section() section.append(EmailRow(){ $0.tag = "email" $0.title = "Email" }) form += [section] } func tableView(_ tableView: UITableView,willDisplay cell: UITableViewCell,forRowAt indexPath: IndexPath) { print("NOT CALLED") } override func tableView(_ tableView: UITableView,didSelectRowAt indexPath: IndexPath) { print("will be called") } override func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell { print("GETS CALLED") return super.tableView(tableView,cellForRowAt: indexPath) } } /// somewhere else: self.navigationController?.pushViewController(MyViewController(),animated: true)
使用此设置,将调用tableView(_:cellForRowAt :)的覆盖版本(意味着正确设置了tableView.delegate).不会调用tableView(_:willDisplay:forRowAt :).只要我在Eureka中添加一个空白实现,我就可以覆盖该方法.
问题:为什么Swift在超类中没有默认实现时不使用该方法?
解决方法
我自己也注意到了这个问题,这对我来说似乎是一个错误.你有两个选择.
首先,您可以在扩展中实现委托方法,并在子类中覆盖它.这将确保调用该方法.
extension FormViewController : UITableViewDelegate { func tableView(_ tableView: UITableView,forRowAt indexPath: IndexPath) { // you can leave the implementation blank if you want } } class MyViewController: FormViewController { override func tableView(_ tableView: UITableView,forRowAt indexPath: IndexPath) { print("CALLED!!") } }
其次,您可以使用pre-Swift 3表示法声明该方法,它将起作用.这部分对我来说也是一个错误(或同一个bug的所有部分).我不推荐这个选项,因为它可能会在未来的Swift或Xcode版本中发生变化,并且通常会感觉很乱.
extension FormViewController : UITableViewDelegate { // no willDisplayCell method } class MyViewController: FormViewController { func tableView(_ tableView: UITableView,willDisplayCell cell: UITableViewCell,forRowAtIndexPath indexPath: NSIndexPath) { print("CALLED!!") } }
编辑:OP将UITableViewDelegate方法放在扩展中的事实不会导致问题.即使类本身对委托进行了decalres,问题仍然存在.