Declarative UIKit? Why Not?

Nayanda Haberty
Nerd For Tech
Published in
5 min readJun 16, 2022

I know all of you we’re all excited about the new SwiftUI. The declarative approach is way way more better and elegant than anything UIKit has to offer. Yes, UIKit has storyboard and XIB, but that will eventually become a pain in the a**.

Declarative UIKit?

Yes! We can still use UIKit but in a declarative way! All you need to do is use Draftsman (yes it’s my own library) as a UIKit declarative UI builder. You can check its Github page for more information.

Let’s try Draftsman!

Let’s create a mini-project to try this library. our goal is to create a simple UI like this with Draftsman:

Very simple indeed. But what we want to achieve is not a complex UI, but proof that we can use a declarative approach using UIKit.

Let’s create a project!

Don’t forget to add Draftsman as its dependency. You can use Swift Package Manager or Cocoapods, which one you prefer. In this example, I’m using Swift Package Manager, since it’s available out of the box:

When you are done, please take a look at the newly auto-created ViewController class:

Now import Draftsman and implement the Planned protocol:

What we are doing here is declaring what the subview of the ViewController view will have inside a viewPlan property. Don’t forget the LayoutPlan attributes, it’s the resultBuilder implementation used to make this approach possible. applyPlan() then will read the viewPlan declaration and build a view as declared in there. We will mostly be focused on what we write in the viewPlan.

Now let’s see what happens if we compile the project:

Blank?

Don’t panic, the UILabel is actually there, but the size is zero, that’s why. What is missing is the UILabel constraints. Let’s add one in the viewPlan:

As you can see there, you need to use drf from the view to extract the compatible anchor. The center that we use here represents centerYAnchor and centerXAnchor, and we constrained it with the same anchor from its parent. Now if you compile it the label should be right in the center of the screen:

Use UIStackView

Well, if you see what we want to achieve, it will be easier if use UIStackView, right? Then let’s use one:

Now we declare the UIStackView with its constraints. Horizontal is represent the leftAnchor and rightAnchor, and vertical represents the topAnchor and bottomAnchor. Now to make sure it will use safeAreaLayoutGuide, we constrained it with safeArea.

insertStacked is equivalent with addArrangedSubview as now UILabel is part of UIStackView arrangedSubviews. Since now UILabel constraints are managed by UIStackView, we need to set its alignment to the center to make it centered. Draftsman using Builder (Yes, my own library too) to enable the ability to use builder pattern out of the box. All you need to do is just use builder after drf.

Let’s continue building the UIStackView content:

myVeryLongText is just a variable that should look like this:

Now let’s compile:

Not quite right yes?

This result is actually expected. It’s because our UILabel did not have a verticalCompression priority set so it compresses the label and truncates its text. The fix is easy:

Well doesn’t look good, is it? We can actually compose ViewPlan into another ViewPlan like this:

Much better right? You can compose ViewPlan as much as needed with function or property getter. Just don’t forget to add LayoutPlan attributes on top of it.

As you can see on the code, I added offset(by: 24) to the vertical and horizontal of UIStackView. This will add space by 24 to the outer part of the view. If you want to add space to the inside, use inset(by:).

Now let’s compile it and see:

Almost Done!

UITextField and Keyboard

Now to the last part. We will need UITextField and of course, it will show a keyboard. Adding UITextField is the easy part, but don’t worry, being constrained to the keyboard is as easy too!

Let’s start with TextField first:

We want to make the UIStackView bottom be constrained to the top of the UITextField container, that’s why we will need it to be stored as a variable so it could be used in viewPlan. The customField is constrained to be at the bottom of the view. Everything looks good, except for one thing. It ignores the keyboard:

Not good eh?

Fortunately, you can always use keyboard anchor as a constraint, even if you are supporting an older iOS version since it’s powered by Clavier (once again, this one is mine too). Let’s add it:

It’s should be finished now, but we can always make the customField it’s own separated view component in case it will be used by the other. To make a custom UIView, all you need to do is just create a class extend any UIView, and implement Planned, just like before:

Then it can be used in our ViewController as CustomField:

Let’s compile it and see:

Yay!

You did it! You create a simple app using the declarative approach with UIKit! Let’s review the finished ViewController code:

You can clone the example at this repository -> DeclarativeUIKitExample

Final Notes

If you miss the repository link for the Draftsman, here it is -> Draftsman. This is just part 1 of Declarative UIKit. There will be part 2 which will talk about how to add a reactive approach here and the last part where we will create a full MVVM architecture from this.

--

--

Nayanda Haberty
Nerd For Tech

I love programming and learning. Expert in iOS, but also did Android, Backend, and Web Dev. Programming is fun and I enjoy exploring different tech stacks.