Protocol Oriented Programming View in Swift 4

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

Bob Lee
Bob the Developer
4 min readJan 18, 2017

--

Learning POP is like finding gems through cyclopedia/blogs

Last update on May 15th, 2017 | Swift 3.1

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)

Protocol Oriented Programming Series (YouTube)

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}
}

The content has been fully migrated from Medium to the personal blog. If you wish to finish reading the rest of the article and learn about practical protocol oriented programming, feel free to visit the new platform here.

--

--