How many views does an APP make?
With coded views and creativity this number could be less than you think
My motivation in this text is to not judge the tools. But showing another way to build an APP without interface builder, using iOS native APIs and enjoying this process with creativity. In this post you will learn about:
- Anchor Layout
- Stack Views
- Dependency Injection
- Data traffic
Storyboards? XIBs? Coded views?
Starting with a polemic subject 🙃. Both my first steps into Xcode and some professional work were done with the Storyboard. I could not imagine how anyone could replace the drag and drop with interface builder by code. Because, it’s very simple and fast.
Until the Storyboards started to bother me and then the XIBs too. Before I preferred views built with code, I was very resistant to this change. But one day I began to reflect and I concluded that it was laziness on my part. After all, when fullstack developer I wrote HTML instead of dragging and dropping components (like old Dreamweaver). But for me the Visual Format Language and the
NSLayoutConstraint constructor are boring to use.
Visual Format Language is very sensitive to typo failures. And the default constructor of
NSLayoutConstraint is to long.
So I participated in some talks of Thiago Lioy @tpLioy about view code. In these talks he showed how he migrated a Storyboard project to views created with code using Snapkit. And the result, to my surprise, was very good. And that is how I started to like view code, thanks @tpLioy. But I still wanted to learn how to use what Apple did for us. That’s when I met the Anchor Layout.
The Apple documentation describes
NSLayoutAnchor as being a class factory, intended to generate
NSLayoutConstraint objects are responsible for enabling Auto Layout.
NSLayoutAnchor will make it easier to create constraints used in auto layout. Instead of creating the constraints using the constructor of the
UIViews methods are used. The advantage will be a cleaner code and a type check to avoid creating invalid constraints. This checking will not allow, for example, mix X-axis attributes with Y-axis attributes.
NSLayoutAnchorclass provides additional type checking, it is still possible to create invalid constraints. For example, the compiler allows you to constrain one view’s
leadingAnchorwith another view’s
leftAnchor, since they are both
NSLayoutXAxisAnchorinstances. However, Auto Layout does not allow constraints that mix leading and trailing attributes with left or right attributes. As a result, this constraint crashes at runtime.
Time to action
To demonstrate how to use layout anchor in practice, I created a Playground. In this playground there will be a list of business cards. Where the cards have a different view according to the plan chosen by user. With that in mind, I created the layout below.
The root of everything
As you can see, all business cards have the same data. But, displayed differently. If you have ever work with front-end Web, it like to had a single HTML, with a different CSS for each layout. So, I am going to create a class containing all elements of the card component and after the “css”.
At this point we will have code repeating. But, calm down, at the end of the post this code will be refactored. And that is one of the advantages when building code views, we are free to put our creativity into practice and evolve what is being done.
To design all the cards for a design pattern Dependency Injection is used. The object to be injected will be a
BusinessCardComponents that will receive presentation instructions in the
Although there are few constraints, the code has been somewhat extensive. Because of the pain to do this code several times I created an extension. This extension will facilitate the use of Layout Anchor. Below, I show how the extension was and how the code was later.
It took more lines because I found it convenient to break them. But overall it was a reduction of almost 800 characters. And beyond the economy of characters, it became an easier code to read. Continuing, the next screen refers to the Full plane.
Now when our application displays Full Plan business cards, it should show the image at left of the data, rather than on top. For this, I created a view called
rightContentContainer that will contain the content to the right of the image, with its leading equal to the trailing of the image.
Now, to make the view of the Junior plan, I suggest a different way. Using Stack Views instead of just Anchor Layout. In particular, both with Interface Builder and through code, I layout with constraints and then change to use Stack Views when appropriate.
As the name suggests, it is an object that will stack views horizontally or vertically. Because of this stack structure, we avoid creating some constraints. All that has been demonstrated previously using Anchor Layout can be simplified even further by using Stack Views.
A stack view employs Auto Layout (the system’s constraint-based layout feature) to arrange and align an array of views according to your specification. To use a stack view effectively, you need to understand the basics of Auto Layout constraints as described in Auto Layout Guide.
JuniorBusinessCardView code is even simpler with fewer rows in the part that defines the constraints. In addition to the positioning of views, it is also possible to change font size, colors and so on, as per the code below.
An Entity could easy be used inside the component. But sometimes the entity has more information than the component need. And to make a clean code, we must request only the necessary data.
In addition to not using all the data of an Entity, the next programmer will not know what that entity should be filled in order for the view to works correctly. Unless he opens the
BusinessCardComponents class and discovers all the values used. To solve this pain I have two suggestions.
The first suggestion is to put in the function that will fill the screen, all parameters used. A bad thing is that we can have a function with a very long signature. Look:
And the second alternative I have used at different times. Create a typealias of what would be in the method signature. So the signature gets smaller and we can still use Xcode help (option + click).
When it comes to views built with code we have several solutions and “there is no silver bullet”. On the positive side, we can work with our creativity to be more productive. I think the Interface Builder ends up limiting us and accommodating us.
In practical terms if the choice was to use Storyboard or XIBs we would have three screens drawn with little reutilization. In addition, it would be more difficult to create tests and data traffic would also be more costly.
Code views require new learning. But it is a low learning curve. Try to get out of the comfort zone of Interface Builder, learn more about UIKit, improve your creativity and, in the future, gradually increase your productivity.