How Do You Do UIView<SomeProtocol> in Swift?

In Objective C, you’ll often find code like:

UIView<Droppable> *targetView = …;

This is a variable (or parameter or @property) that says “I need a thing that conforms to the Droppable protocol and which is some kind of UIView.” Basically, you need to be able to treat this thing like a view, and also like a Droppable.

It turns out this is kind of hard to do in Swift! There’s no natural syntax to express this, but here’s a trick we use at Khan Academy that helps us accomplish the same goal (it’s not exactly the same thing, but it’s close enough to be useful):

We make our protocol like usual, but we add an extra property to represent the view:

protocol Droppable {
    func dropped() // and other methods / properties
    var view: UIView { get } // this property lets us treat Droppables like views
}

So, anything conforming to Droppable is expected to also return a view. Now when we have a Droppable property, it has-a view (which isn’t exactly like the Objective C way, where Droppable is-a view, but it’s close enough), and we can access this view with a simple myDroppable.view.

But it’d kind of suck to have to implement this view property on every view conforming to Droppable, so we then use Swift’s protocol extensions to give an implementation to all UIViews in the module:

extension Droppable where Self: UIView {
    var view: UIView {
        return self
    }
}

And voilà! It’s not a perfect translation of how we accomplish this in Objective C, but it works! Can you think of any ways to improve this?

Join the Discussion 👂🤔✍️

Please read the Discussion Guidelines before replying.

☑️ Email me when someone replies.

Speed of Light