UIKit: how to build more simplified views?

Brenno de Moura 🏳️‍🌈
4 min readSep 18, 2022

--

A few months ago, the need to make the process of building views more simplified has increased.

Normally, when implementing the UIView, we needed to create the lazy var contentView, the init, implement the ViewCodable protocol (buildHierarchy, setupConstraints, applyAdditionalChanges) and then we had our View ready to use. However, this process has become quite repetitive and standard, always inserting the same code in all views. The same thing happened in the view controller.

The solution that came to my mind was the View from SwiftUI, as it is perfect in requiring only the body to implement our view. How to do this in UIKit? Is it possible?

After months, I came across this article on a Friday night:

This made me think a lot about putting together everything I already knew about programming in Swift. I’m happy to make this solution available to the community and help the development of several projects that face the same issue, but there is still no solution similar to SwiftUI.

ContentViewProvider

Starting with SwiftUI inspiration. The ContentViewProvider protocol contains the associatedtype to allow the implementation of our SwiftUI body-like view.

PrimitiveViewLoadable

The second protocol is the PrimitiveViewLoadable, responsible for connecting the ContentViewProvider protocol with our view and has only the loadView() method.

I chose this name to be similar to the UIViewController’s approach. I don’t know if I’ll find a more refined solution to these problems, but this was the one that met the project’s needs.

After implementing the protocol, we need to extend the ContentViewProvider with the PrimitiveViewLoadable.

PrimitiveView

The worst part of the solution, but perhaps the joy of some, is the implementation of PrimitiveView, which is absolutely necessary. Here is where we can combine various techniques.

The first one is the use of @available(*, unavailable) shared by the codeinswift.io medium. We can disable the implementation of init(frame:) and init?(coder:) to make our declarative view clean.

The second most useful (optional) technique in projects is the ViewCodable approach, present directly in the PrimitiveView. As in the project we use a lot of extensions with MARK, I put @objc to continue with the separate code, but its use here is totally optional.

And the third technique is to use the PrimitiveViewLoadable to call, add and configure the constraints of our contentView. Remembering that our goal is to get to the result of SwiftUI. With that, we arrive at the following code.

BaseView

Finally, we need to define our BaseView that joins the PrimitiveView with the 2 protocols we created. I did this simply using Swift’s typealias.

Practical use

That done, it is now possible to implement our views without inits, without ViewCodable protocols and without using constraints, depending on the level of abstraction made on top of the UIKit to make it declarative.

The use of the setting and the definition of the margin, scrollable is part of another article about view code I wrote on medium.

ViewController

For the view controller we can use the same resources and abstract the implementation of init?(coder:), init(nibName:bundle:) and loadView.

PrimitiveViewControllerLoadable

The UIViewController contains the loadView and I used the same name to get a similar result. The difference is that Loadable’s loadView returns a UIView.

In this case, we can leverage the ContentViewProvider protocol we created to extend it with the PrimitiveViewControllerLoadable.

PrimitiveViewController

So, we implement our PrimitiveViewController making use of the techniques detailed in this article.

BaseViewController

We make the typealias combined the protocols and the view controller, as shown in the code below:

Practical use

With that, the view controller doesn't have the inits and the loadView method. The protocols and the PrimitiveViewController do everything for us by decreasing the repetition of important but unnecessary code. And of course, similar to the view, depending on the level of abstraction made on top of UIKit to make it declarative, we have code like this:

Conclusion

Thanks guys for reading this far! The material I find on this platform has helped me a lot to discover new ways to write code and I hope this solution will also help you to do amazing things with Swift.

Thanks for reading this far! If you liked this content see also: UIKit: rendering components in SwiftUI.

If you would like to contribute so that I can continue producing more technical content, please feel free to buy me a coffee ☕️ through the Buy me a Coffee platform.

Your support is essential to maintain my work and contribute to the development community.

--

--

Brenno de Moura 🏳️‍🌈

Software engineer with a passion for technology and a focus on declarative programming, experience in challenging projects and multidisciplinary teams