Encode Behaviors into Reusable View Controllers

Using the American spelling

Image for post
Image for post
Photo by Jonathan Hanna

Difficulty: Beginner | Easy | Normal | Challenging
This article has been developed using Xcode 12.1, and Swift 5.3

Prerequisites

Extension: Extensions add new functionality to a class, struct, enum or protocol

Override: The process in which a subclass changes a method, property or type in the parent class Protocol: A blueprint on methods, properties and requirements to suit a piece of functionality

UIViewController: A view controller is an intermediary between the views it manages and the data of your app

Break down!

The principle here is that we are trying to break view controllers up — which essentially is attempting to make iOSs UIViewControllers more closely follow the Single Responsibility Principle.

Now this is an article I’ve written to support a blog post by Soroush along with a similar post by Bryan — however I failed to follow either of these propertly for the appearance and suppression of the UINavigationBar, so this article covers that (so all credit goes to Soroush and Bryan).

The example behaviour

Within this article we are going to hide the UINavigationBar in the first of two UIViewController instances within a UINavigationController. In order to do so this article will use the function:

(we shall see that concrete implementation later).

The solution

We are using Swift, so it makes sense that we would want to use protocols

The protocol It is possible to use any of any of the UIViewController lifecycle events in order to implement these behaviours.

The protocol

This protocol is called ViewControllerLifecycleBehavior:

Now to prevent each behaviour needing to implement every single part of the lifecycle we can create default implementations within a protocol extension

Now rather than using a base class for a view controller, which I’ve previously claimed is doing it wrong instead we are going to use an extension on the UIViewController class and then implement a function to add behaviors into the UIViewController class. Unfortunately we are going to need to override viewDidLoad() and other lifecycle methods.

This can then be called in the viewDidLoad() method of the ViewController class.

which then calls the following struct:

of course — this only needs to be called in the first view controller (that is, the one where I would like the navigation bar to be hidden).

Other uses

This behavioural method is suitable for perhaps loading analytics, or changing the color of a UINavigationBar, making the back button empty on a UINavigationBar amongst other behaviours. Wonderful!

Conclusion

So we have found a way to avoid the use of big view controllers, or horrible base classes.

I hope this article works as a companion to by Soroush and Bryan’s work while providing a full implementation for you to download from the repo. I hope this helps in any case.

If you’ve any questions, comments or suggestions please hit me up on Twitter

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store