CloseHomeAboutBlogCourse
Bob I’m an iOS instructor/blogger from S.Korea.July 14 • 5 min read • Edit

Protocol Oriented Programming View in Swift

Learn how to animate buttons, labels, imageView without creating bunch of classes

Motivation

You’ve heard knowledge without execution is like having teeth but only drinking milk. You ask, “Okay, enough of theories. How can I start using POP in my app?” 🤔

In order to drink the most juice out of your time with me, I expect my readers to understand Completion Handlers, and create basic implementation using Protocol. If you aren’t comfortable with them, I ask you to kindly leave and then watch some of my articles and videos below and come back after.

Prerequisite:

No Fear Closures Part 2: Completion Handlers (Medium)

Intro to Protocol Oriented Programming (Medium)

What I think you will learn

You will learn how to use Protocol to animate UI Components such as UIButton, UILabel, and UIImageView. I will also show you the differences between traditional methods vs the POP way. 😎

UI

The demo app called, “Welcome to My House Party”. I’ve made this app to verify if I’ve invited you to my house party. You have to enter your invitation code. There is no logic behind this app. If you press the button, things will animate regardless. There are four components that animate, passcodeTextField, loginButton, errorMessageLabel, and profileImageView.

There are two animations: 1. Buzzing 2. Popping (Flash)

Completed Project

Don’t worry about getting it down. Just flow like water with me for now. If you are impatient, just scroll, download the source code, and you may dismiss.

Things Back Then

To fully grasp the power of POP in real apps, let’s compare with the traditional. Let’s say you want to animate UIButton and UILabel, You might subclass both and then add a method to it.

class BuzzableButton: UIButton {
 func buzz() { // Animation Logic }
}

class BuzzableLabel: UIButton {
 func buzz() { // Animation Logic }
}

So, let it “buzz” when you tap on the login button

@IBOutlet wear var errorMessageLabel: BuzzableButton!
@IBOutlet wear var loginButton: BuzzableLabel!

@IBAction func didTapLoginButton(_ sender: UIButton) {
 errorMessageLabel.buzz()
 loginButton.buzz()
}

Do you see how we are repeating ourselves? The animation logic is at least 5 lines, and there is a “better” way to go about using extension. Since UILabel and UIButton belong to UIView, we can add

extension UIView {
 func buzz() { // Animation Logic }
}

So, BuzzableButton and BuzzableLabel contains that buzz method. Now, we are no longer repeating ourselves.

class BuzzableButton: UIButton {}
class BuzzableLabel: UIButton {}

@IBOutlet wear var errorMessageLabel: BuzzableButton!
@IBOutlet wear var loginButton: BuzzableLabel!

@IBAction func didTapLoginButton(_ sender: UIButton) {
 errorMessageLabel.buzz()
 loginButton.buzz()
}

Okay, then why POP? 🤔

As you’ve seen, the errorMessageLabel, which states, “Please enter valid code 😂” also has one more animation to it. It appears and fades out. So, how do we go about with the traditional method?

There are two ways to go about this. First, you could, again, add another method to UIView

// Extend UIView
extension UIView {
 func buzz() { // Animation Logic }
 func pop() { // UILabel Animation Logic }
}

However, if we add methods to UIView, the pop method will be available to other UIComponents besides UILabel. We are inheriting the unnecessary functions, and those UIComponents become bloated by default or to emphasize, as f.

The second way is by subclassing UILabel,

// Subclass UILabel
class BuzzableLabel: UILabel {
 func pop() { // UILabel Animation Logic }  
}

This works okay. However, we might want to change the class name to BuzzablePoppableLabel to indicate clearly just by looking at the name.

Now, what if you want to add one more method to UILabel to clearly indicate what the label does, you might have to change the class name to, like BuzzablePoppableFlashableDopeFancyLovelyLabel. This isn’t sustainable. Of course, I’m taking it pretty far.

Protocol Oriented Programming

Okay, you have come this far, and you haven’t recommended this article yet, gently tap that and continue.

Okay, enough of subclassing. Let’s create a protocol first. Buzzing first.

I didn’t insert code for animations since they are quite long, and gists aren’t natively supported by mobile apps.

protocol Buzzable {}

extension Buzzable where Self: UIView {
 func buzz() { // Animation Logic}
}

So, any UIComponents that conform to the Buzzable protocol would have the buzz method associated. Unlike extension only those who conform to the protocol will have that method. Also, where Self: UIView is used to indicate that the protocol should be only conformed to UIView or components that inherit from UIView

Now, that’s it. Let’s apply Buzzable to loginButton, passcodeTextField, errorMessageLabel, and profileImageView But, wait, how about Poppable?

Well, same thing.

protocol Poppable {}

extension Poppable where Self: UIView {
 func pop() { // Pop Animation Logic }
}

Now, it’s time to make it real!

class BuzzableTextField: UITextField, Buzzable {}
class BuzzableButton: UIButton, Buzzable {}
class BuzzableImageView: UIImageView, Buzzable {}
class BuzzablePoppableLabel: UILabel, Buzzable, Poppable {}

class LoginViewController: UIViewController {
  @IBOutlet weak var passcodTextField: BuzzableTextField!
  @IBOutlet weak var loginButton: BuzzableButton!
  @IBOutlet weak var errorMessageLabel: BuzzablePoppableLabel!
  @IBOutlet weak var profileImageView: BuzzableImageView!

  @IBAction func didTabLoginButton(_ sender: UIButton) {
    passcodTextField.buzz()
    loginButton.buzz()
    errorMessageLabel.buzz()
    errorMessageLabel.pop()
    profileImageView.buzz()
  }
}

The cool thing about POP is that you can even apply pop to any other UIComponents without subclassing at all.

class MyImageView: UIImageVIew, Buzzable, Poppable

Now, the name of the class can be more flexible because you already know available methods based on the protocols you conform, and the name of each protocol describe the class. So, you no longer have write something like, MyBuzzablePoppableProfileImage.

Too long, didn’t read:

No more Subclassing

Flexible Class Name

Feel caught up as a Swift Developer

Last Remarks

I hope you’ve learned something new with me. If you have, please tap that ❤️ to indicate, “yes”. If you’ve found this implementation useful, make sure share so that iOS developers all around the world begin to use Protocol Oriented Views to write fewer lines of code and modularize. Now, if you wish to take your Swift game to the next level, feel free to join the Swift intermediate course. You will learn about advanced enums, intro to functional programming, generic protocols, and more. Learn Swift with Bob.

Resources

Source Code

About Me

iOS Developer from South Korea. Feel free to follow my story on Instagram or get serious on LinkedIn