User interface programming on iOS at Ackee (Storyboards vs. Xib vs. code)
The creation of user interface in iOS is always a passionate topic among developers. These are divided into two groups: First are those who love creating GUI in Interface Builder, and then those who hate it. For the 5 years I have been working on this platform, I exchanged memberships in these clubs several times to find out that nothing is black and white and everything has its pros and cons. So that you don’t have to go through this, I wrote this article, which is kind of a thorough summary of my remarks regarding these technologies.
Storyboards vs. Xib vs. custom code
There are generally three ways to create user interface in iOS. I will not describe them here in detail since there are many better online articles about this. Rather, I want to focus on the problems of these accesses and also on when it is appropriate to use which one.
Storyboards are the youngest of the three mentioned methods for creating user interfaces. It is the canvas on which we create the design of individual screens, combine them through transitions and fill with static data. A lot of programmers, however, are unable to properly use them. The fundamental mistake (and I had previously committed it as well) is to store the entire application in one storyboard. The storyboard is then very confusing and most of all, painfully slow. Applications should be divided according to logical units and each of them should have their own storyboard. As an example of such a logical unit you can imagine a tutorial or shopping cart checkout.
The big advantage of storyboards is their visual explicitness. Anyone who looks into it sees what relationship the screens have with each other and what is the application flow. Another advantage is rapid prototyping, because it is easy to click on the screens and transitions between them in Interface Builder. However, if you want to transfer some data between screens as well, in the case of Segues we will end up with the giant prepareForSegue method with many if/else statements.
Among the disadvantages I would include very limited code reusability, especially graphic elements, from very similar controllers to the cells in the table. However, Storyboards have undeniable simplicity with which you can create, for example, a static table for user login, which is exactly the thing done in an unnecessarily complicated manner in a code.
Xib is (like Storyboards) created in Interface Builder, but unlike the Storyboard it represents only one specific view element (view, controller, table cell, etc.). Thus, although it loses the notorious storyboard clarity and insight, it gains reusability and control over application logic. Unfortunately, however, it entails other work maladies in Interface Builder, which we will discuss below.
A lot of people would say about the GUI programming in code that it is a tedious and boring process. And in some ways they are certainly right. I know a lot more fun programming activities than writing and positioning Labels. Despite all this, I think that writing GUI in one’s customized code is much better than using Interface Builder. I will explain why in a few points:
If the application is not a complete circus, it mainly uses a single set of elements that look the same across the application. In the code, I can prepare these buttons, texts, avatars, etc. and have all the UI elements in one place. Moreover, I can also reuse them across projects.
Regarding embedded controllers, Storyboards have a clear lead. The ease with which I can insert one controller into another one using Interface Builder is unmatched, while in the code it is an unnecessarily lengthy and painful process.
If I need to change a color, font size, font style, etc. in the application, I can simply edit the desired feature in one place and the change is reflected everywhere, provided that I have a correctly designed code and adhere to some principles. It does not then matter if I work on a multibranding application or develop with agility as the requirements change — I am always able to react very flexibly to changes.
3. (No) fragmentation
In the code, I have everything in one place. Proponents of IB (Interface Builder) will oppose that they can click on the design in IB and then set attributes such as font and color globally via the code as I did. Yes they can, and I know about that, but from my experience it creates more problems rather than does good — part of GUI logic is in Storyboards and part in the code. When someone returns to the code, they have to painstakingly look to see which attribute is set. Despite the fact that some of the attributes cannot be set through IB (yes, I can set the values in userInfo in IB, but it is perhaps the worst programming pattern that can be performed through XCode). In short, when writing a code, everything is in one place and everyone knows where to look, even if it is a completely new project.
4. Work by more people
Here I will be very brief. Have you ever tried to merge Storyboard/Xib? Have fun :)
Although the localization of IB files is possible, it is quite arduous even for a programmer who must follow the storyboard-generated identifiers for individual elements. God forbid, what about the translator who instead of getting the key in the form:
“login_field_name_title” = “Name”;
“l3f-5abg-iddqd” = “Name”;
Although this problem can be solved by different scripts, it’s extra work.
6. Dynamics (not to mention animation)
Storyboards are simply static and we live in a time when applications are filled with a variety of animations and transitions. It is problematic to click them in IB, not to mention their “own hierarchy and its own containers”.
The last argument is very tied up with the following point. Quite often, we need to hide some elements in the hierarchy depending on the data, which in turn clogs fragmentation. Alternatively, what if I need to alter constraints of individual views in response to these changes?
7. Autolayout (sizeclasses)
Although the situation has generally improved in many ways, for me (and my colleagues) work with constraint in IB is still hell. I need to mark a specific view, then click twice to set autolayout, not to mention relationships and how to set a global padding across applications. In contrast, the work with a Snapkit type library is literally a pleasure. All views are laid out logically in one method, as they follow each other, and thanks to a very readable inscription I can immediately see all constraints and ties and do not ever need to expand individual elements.
If you’ve read this far, you probably already know the opinion we hold on the creation of UI at Ackee. We write UI in a code, unless there is a compelling reason (e.g. historical), why do it differently. Although I’m aware that the writing and positioning of labels may be boring, slow and tedious on some screens, I’m sure that thanks to all the things mentioned above we save a lot of time and frustration in the result. However, I don’t condemn Storyboards for the future in any way. Some functions (such as buggy IBDesignable) are really cool and I like to use Storyboards during lectures at CTU, where it is really a 100 times faster to click on GUI in IB, rather than to write it in code. Likewise, I would always use it for prototyping.
Never say never, I will closely follow the situation around the IB, but until they solve those very pressing problems (whether it is even possible to solve), I will remain faithful to the formation of GUI in code :)