Reputation: 7307
I was hoping this would work:
protocol Foo : UITableViewDelegate{
}
extension Foo{
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
print("ROW:\(indexPath.row)")
}
}
class MyVC : UITableViewController, Foo{
//...
}
No luck though, the method does not get called. Am I missing something, or is this genuinely not possible?
Also, there is no compiler warning/error, the method is just not being called, which some may consider a bug.
Upvotes: 1
Views: 462
Reputation: 14795
I think this is because your are inheriting from UITableViewController
which already implements UITableViewDelegate
.
You can easily test this:
class MyVC: UITableViewController {
func tableView(tableView tv: UITableView,
didSelectRowAtIndexPath ip: NSIndexPath) {}
}
This will result in
error: overriding declaration requires an 'override' keyword
The compiler assumes the method is already implemented in the direct inheritance chain. Hence your default method from the protocol won't be picked.
Having said that, the variant below does not work either. Adding @objc
to the protocol makes my swiftc segfault ...:
import UIKit
protocol Foo : UITableViewDelegate {
func tableView(tableView: UITableView, didSelectRowAtIndexPath: NSIndexPath)
}
extension Foo {
func tableView(tableView: UITableView,
didSelectRowAtIndexPath _: NSIndexPath)
{
print("abcXXX")
}
}
class ViewController: UIViewController, UITableViewDataSource, Foo {
override func loadView() {
self.view = UITableView(frame: CGRect())
}
var tableView : UITableView { return self.view as! UITableView }
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.delegate = self
self.tableView.dataSource = self
self.tableView.registerClass(UITableViewCell.self,
forCellReuseIdentifier: "MyCell1")
}
func tableView(tableView: UITableView, numberOfRowsInSection _: Int) -> Int {
return 3
}
func tableView(tableView: UITableView, cellForRowAtIndexPath ip: NSIndexPath)
-> UITableViewCell
{
let cell = tableView
.dequeueReusableCellWithIdentifier("MyCell1", forIndexPath: ip)
cell.textLabel?.text = "p[\(ip.row)]"
return cell
}
}
Hence I assume my answer is only 50% right. Presumably protocol extensions only work in static binding contexts, which excludes ObjC protocols?
Update: This seems to be the proper answer: Protocol-Oriented Programming with UIKit. The essence:
What we CAN'T do: Provide default implementations for Objective-C protocols.
Upvotes: 1