Protocol-Oriented Views in Swift

Join me for a Swift Community Celebration 🎉 in New York City on September 1st and 2nd. Use code NATASHATHEROBOT to get $100 off!

I recently gave a talk on Practical Protocol-Oriented-Programming(POP💥) in Swift. The video is still being processed. Meanwhile, here is the written-up version of the POP View part of the talk for reference (for me and anyone else!).

The Setup

Let’s say you have a simple app with an image an a button. The product manager wants the image to shake when the button is pressed:

Since this is a common animation used when the user’s username or password is wrong, it is easy to find the code for it on StackOverflow (as any good developer would 😁).

The hardest task here is figuring out where to put the code, which is not that hard. I’m just going to subclass the ImageView and add a shake() method to it.

Now, when the user presses the button, I can just call the shake method on the view:

Nothing exciting here. I’m done and I can move on to other tasks… Thanks StackOverflow!

Extending Functionality

However, just like in real-world development, just when you think you’re done and moving on, the designer comes over and says that they also want the button to shake with the view…

You can of course just do the same thing – subclass the button and add a shake method:

And now you can just shake both views when the user clicks the button:

But hopefully you stop yourself… Having the shake() code in two places violates the DRY (don’t repeat yourself) principle. If a designer comes over in the future and asks for more or less of a shake, you’ll have to change the logic in both places, which is not ideal of course.

So how do you refactor this?

The Usual Way

If you come from Objective-C, you likely just put the shake() code into a UIView Category (extension in Swift):

Now, both the UIImageView and the UIButton (and every single other view), has the shake() method available:

However, as you can immediately see, there is now nothing particularly in the FoodImageView or ActionButton code that shows that there is an intention for it to shake. It’s just a random method that you know is there because you wrote the extension (aka category).

Furthermore, the Category pattern can easily get out of hand. It tends to become a dumpster for code that you don’t know where else to put. Soon, there is so much there, you don’t even know why it’s there and where it’s supposed to be used. A bit more on why Categories are considered harmful here.

So what to do… 🤔

Protocols FTW!

You guessed it! The Swifty solution is to use protocols! We can use the power of protocol extensions to create a Shakeable protocol with a default shake() implementation:

Now, we just add the Shakeable protocol conformance any views that we actually intend to have shake:

The first thing to notice here is the readability! Just by looking at the class declaration of the FoodImageView and the ActionButton, you can immediately see that it’s meant to shake.

If the designer comes over and also wants the view to Dim a little while shaking, we can use the same protocol extension pattern to add that functionality, making for super nice composition.

And when the product manager no longer wants the view to shake, it is super easy to refactor. Just get rid of the Shakeable protocol conformance!


By using protocol extensions for view composition, you’re adding super nice READABILITY, REUSABILITY, and MAINTAINABILITY to your code base.

P.S. I also recommend reading the Transparent View Controllers and Dim Backgrounds tutorial for more advanced applications of this pattern 🙊

Enjoy the article? Join over 20,000+ Swift developers and enthusiasts who get my weekly updates.

  • olavgm

    So, instead of an extension with one method, you end up with a protocol, and extension to the protocol and two subclasses.

    I’m sorry, but that’s not what I’d call a better solution.

    • Xaver Lohmüller

      As mentioned, readability is a key point of choosing this approach. You might need to subclass anyway, and this makes you aware you are using code that isn’t part of UIKit or whatever.
      In a recent project, I was using an extension without realizing that it was written and later changed by a coworker (until bugs and crashes started to appear).

      In objc, this was less of a problem because you had to import categories that you wanted to use.

      • olavgm

        Sorry, still not convinced. I understand what Natasha is trying to do here, but if I read this code I can do two things:

        a) go to the subclass of both the view and the button, see that they are Shakeable, go to the Shakeable protocol, then look for the extension and then read the shake() method.

        b) go to the shake() method.

        With an extension to UIView I could do just b) without so much code.

        I suggest you watch this talk

        (start at 25:50)

        • digital_signal

          An extension on UIView will make all UIViews shakeable and dimmable. What if you want only certain UIView subclasses to have these behaviours and in different combinations? This is a known pattern in game development (

          “Components are most commonly found within the core class that defines the entities in a game, but they may be useful in other places as well. This pattern can be put to good use when any of these are true:

          You have a class that touches multiple domains which you want to keep decoupled from each other.

          A class is getting massive and hard to work with.

          You want to be able to define a variety of objects that share different capabilities, but using inheritance doesn’t let you pick the parts you want to reuse precisely enough.”

          • olavgm

            It is always a situation of finding the right balance. If you have to enforce that only those controls have the shake() and dim() methods, Natasha’s solution seems to fit nicely.

            But on most situations you won’t need to enforce such thing, so having the extra functionality on all UIView classes seems fine to me.

          • Jeff Sherin

            Couldn’t you also just have a struct with a static function that takes in a view and shakes it? That’s what I used to do in objective C. If you don’t want to do an extension.
            static func shakeView(view: UIView) { … }

            I’m on the fence with a lot of the protocol extension stuff. I’ve tried to dive in but sometimes I wonder if it’s really much of a step forward, at least in cases like this.

        • Mohamed

          mostly what I see here is protocol oriented actions. I mean shake is an action.
          It’s not really not a view.

          Is there anyway that you can just add buttons, labels in this protocol oriented way? AFAIK you can’t extend protocols to just conform and have the button there…

    • Paul Stringer

      There’s an old saying “once you have a hammer, everything starts to look like a nail”

      • davinspir .


    • Maybe this example can help you understand the point of this article.
      Look Swift’s Decodable and Encodable protocols. Not every Class or Struct, is forced to be Codable.
      Maybe in the case of the “Shake” I would also use an extension, but sometimes the Protocol-Oriented approach is more handy.

  • raj

    I am working on a UICollectionView where the cells need to be draggable. Currently, I have the functionality implemented in a ViewController. My question is whether this is possible using a protocol, since dragging or moving a cell would need to take into account the collection view and its content offset (to scroll), the target indexPath etc. Also, if the cell to be moved is selected with a long press, then should another protocol be added for the long press? Thank you.

  • Dmitry Povolotsky

    Well, that is nice if you have custom FoodImageView, but what if it’s just UIImageView?

    • David Bemerguy

      In Swift you could extend UIImageView to adopt the Shakeable protocol and that’s it, here is the code:
      extention UIImageView: Shakeable {}

  • Jake Lin

    Very good article, thanks 👍. Our library is built on top of Protocol-Oriented paradigm, every compoent is a protocol, we can easliy reuse them in any subclass of UIView or even UIViewController.

  • Ted Bendixson

    Yes a million times! Protocol compositions are the way to go! I’ve started using them with SpriteKit in a game I’m developing, and it’s super cool to simply give a game character certain abilities by adding a protocol conformance. It’s really clean and readable. I wish this kind of thing were available in other languages.

  • When I see this, I think about how it could be neat to create a framework of protocol files that do all sorts of things. Then when a developer is shopping for added functionality, they could pluck a file or 2 from the framework, drop it in, see what classes can use it, and have their class conform to it and they’re instantly off to the races with minimal effort.

    Very neat approach.

  • Mazen Kasser

    Nice to have global conformance to UIView i.e
    extension UIView: Shakeable { }

  • Mohamed

    mostly what I see here is protocol oriented actions. I mean shake is an action.
    It’s not really a view.

    Is there anyway that you can just add buttons, labels in this protocol oriented way? AFAIK you can’t extend protocols to just conform and have the button there…