I'd like to define a protocol to be implemented by UITableViewCell kinds of types only and have the compiler enforce this requirement for me:
protocol ProfileTableViewCell: UITableViewCell {
var photoView: UIIimageView? { get }
var nameLabel: UILabel? { get }
}
class DataSource: NSObject, UITableViewDataSource {
let cells = [ProfileTableViewCell]()
// ...implementation continues...
}
Right now, I get compiler errors. To work around this, I have to do things like this:
protocol PersonCell: class { // `class` here is compiled as `AnyObject`
var photoView: UIIimageView? { get }
var nameLabel: UILabel? { get }
}
class DataSource: NSObject, UITableViewDataSource {
typealias Cell = UITableViewCell & PersonCell
let cells = [Cell]()
// ...implementation continues...
}
How hard would it be for a newbie to dive into the compiler source code and make it use the class specified? In this case, UITableViewCell rather than AnyObject?
I'm not quite sure what you want here. Are you trying to extend allUITableViewCells? Only one?
Just a reminder that you can't use a custom toolchain for building iOS apps for the App Store. For a change like this I'd recommend shying away from modifying the compiler.
The feature you ask is not in the language yet β anyone can conform to a protocol. The & syntax on downstream users is how you limit those conformers to use only the right class.
I don't know why people are saying this isn't possible - it is, and I use it all the time. It's especially helpful to annotate that certain protocols are expected to be conformed to by UIViews, for example.
The magic words you're looking for are:
protocol ProfileTableViewCell: class where Self: UITableViewCell {
}
Note:
Technically, the : class part shouldn't be required, but including it helps counter compiler bugs. If you don't include it, sometimes the compiler forgets that these objects are classes and doesn't retain them, and last time I checked, it wouldn't compile in release builds if you mutated a property on a let instance. Include the class constraint, and you'll be fine.
Yes, that's exactly the kind of constraint in the bug report. Slava's latest response was that this wan't implemented yet, which I've assumed means that any apparent support for this is either partial or incidental.
protocol HeaderViewing where Self: UIView {
func set(title: String)
}
let myView: HeaderViewing = MyView()
myView.set(title: "Hello")
...
...
...
self.myView.removeFromSuperview()
/** Value of type 'HeaderViewing' has no member 'removeFromSuperview' */
Hey, I know, a lot of time left :)
Anyway, here is the solution for the Swift 4.2: if you define your myView as UIView that confirmed your HeaderViewing protocol, then it will work:
protocol HeaderViewing where Self: UIView {
func set(title: String)
}
let myView: UIView & HeaderViewing = MyView()
myView.set(title: "Hello")
self.myView.removeFromSuperview()
The superclass constraint is actually redundant -β HeaderViewing already requires every conforming type to be a subtype of UIView. Simply put, every HeaderViewing is also a UIView.
I see, that was certainly a bug. Fortunately is has already been fixed in the upcoming Swift 5 release. This can be confirmed with the latest Xcode beta release.