I have been playing around with protocol extensions and I have a problem. Maybe what I want to achieve can’t be done. I have this playground:
//: Playground - noun: a place where people can play
import UIKit
protocol ArrayContainer {
typealias T
var array: [T] { get }
}
class MyViewController: UIViewController, ArrayContainer, UITableViewDataSource {
typealias T = String
var array = ["I am", "an Array"]
}
extension UITableViewDataSource where Self: ArrayContainer {
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return array.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// Whatever
return UITableViewCell()
}
}
This is what I have and what I want:
ArrayContainer
that just has a typealias and a array which contains objects of this typealias typeUITableViewDataSource
to be used when the class conforms with the ArrayController
protocol. This simply returns the number of items of the array as number of rows. The cellForRowAtIndexPath
method is not well implemented, but it is not the problem.UIViewController
subclass called MyViewController
which implements both protocols.The problem is that the compiler complains because MyViewController doesn’t conforms with UITableViewDataSource
but, as far as i know, it should be covered by the UITableViewDataSource extension. Am I missing something here? or maybe Objective-C protocols can not be extended?
In Swift, you can even extend a protocol to provide implementations of its requirements or add additional functionality that conforming types can take advantage of. For more details, see Protocol Extensions. Extensions can add new functionality to a type, but they can't override existing functionality.
The methods that an object adopts to manage data and provide cells for a table view.
Datasource methods are used to generate tableView cells,header and footer before they are displaying.. Delegate methods provide information about these cells, header and footer along with other user action handlers like cell selection and edit..
I know it's a bit late to respond, and you may not even be looking for this answer, but I just came across this exact issue and needed a real world "solution". You can implement the UITableViewDataSource methods in the class and then immediately hand off the work to the protocol extension like the example below. If swift makes improvements that no longer require this, it's simple to change back to the code in your original post.
//: Playground - noun: a place where people can play
import UIKit
protocol ArrayContainer {
associatedtype T
var array: [T] { get }
}
class MyViewController: UIViewController, ArrayContainer, UITableViewDataSource {
typealias T = String
var array = ["I am", "an Array"]
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return self.internal_numberOfSectionsInTableView(tableView)
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.internal_tableView(tableView, numberOfRowsInSection: section)
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
return self.internal_tableView(tableView, cellForRowAtIndexPath: indexPath)
}
}
extension UITableViewDataSource where Self: ArrayContainer {
func internal_numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func internal_tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return array.count
}
func internal_tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// Whatever
return UITableViewCell()
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With