Within this blog Lai explains the pro’s and con’s of his available options – Storyboards, XIBs and Code.
Recently I came across a situation where I had to completely redesign an internal test iOS app that was primarily developed using XIBs. The main motivation behind this redesign was triggered by deprecation of rounded rectangle buttons which were widely used in our original app. As a result of this drastic change, the clarity and user experience of the app was somewhat diminished. Although this app is only used internally within the Ticketing team, we intended to redesign the user interface in order to improve the usability and intuitiveness. With this task in mind, I investigated the different design approaches and hoped to find an appropriate way to solve my dilemma. I was in two minds whether to maintain the original XIBs approach and making interface changes based on those files or consider a more radical path of introducing storyboards to our project. Before I start discussing these styles in detail, let me explain the terms first.
Generally speaking, thereare three types of UI design approaches.
• Storyboards: were introduced by Apple in iOS 5 as a complete new way for creating and designing use interface. In short, a storyboard is one single XML file which is composed of a collection of screens and the transitions between them. Opening storyboard using Xcode provides us with a built-in visual editor called Interface Builder where we can lay out and design the user interface by adding views such as buttons, tables and text labels. According to Apple’s developer docs, using storyboards is the recommended way of designing UI for iOS applications because the appearance and flow can be easily managed on one canvas.
Figure 1 A basic Storyboard
• XIB (or NIB): Traditionally, NIB files are used to store the user interfaces of iOS apps. In 2007, Apple introduced a new file format with extension .xib as part of Xcode 3.0. Although XIB files share the identical functionality as NIBs, they are better suited for storage in revision/source control systems. Both XIB and storyboard are conceptually pretty similar and are designed to represent the visual objects associated with one single view. As for storyboards, these XIB files can be edited and configured visually using Xcode. Although people would normally associate an XIB with a screen, it is worth mentioning that XIBs are flexible and ideal for storing custom defined components which then can be used together with other object types or just alone. For instance, a custom table cell could be loaded and reused multiple times within different screens (see Figure 2).
Figure 2 Storing a Custom UITableViewCell in a XIB File
• Custom Code: this approach involves no GUI assistance in user interface design, which means programmers need to handle all custom positioning, animation, creation of view objects programmatically. Any interface design created by XIBs or storyboards can also be implemented using pure code. More importantly, what cannot be implemented using GUI tools can always be done using raw code. In certain circumstances, code implementation is the only option to design your interface. A typical example of this arises when dynamic layouts are needed, say we would like the number of table cells to adjust according to content. The most common argument for this approach is that programmers should code and not do visual design. Although storyboards are the latest supplement to the iOS UI toolkit and Apple docs officially recommend storyboards as the preferred approach of designing UI, the other two ways may be used to overcome certain limitations of storyboards. None of these three options can be considered as a replacement for the other two and more importantly, Xcode allows the combination of storyboards, XIBs and customer inside the same project. In the next sections we shall explore the pros and cons of every method and introduce their use cases in our app.
In storyboard terms, a single screen is referred to as a scene, which represents a view controller and its view. The transitions between different scenes are called segues, which are responsible for the visual transition between two view controllers. Due to these storyboard-specific properties, these are some of the benefits storyboards bring:
• Storyboards are best used to represent the UI content of each screen and let you see the transitions and flow of your app.
• Adding segues/specifying navigation and transitions can be performed by simple Control-dragging between scenes. Moreover, storyboards eliminate boilerplate code needed for allocating, popping, pushing and presenting view controllers. Therefore navigation between view controllers is a major simplification in storyboards compared to other two principles.
• By grouping multiple view controllers into one storyboard reduces the total number of files in a project.
• Storyboards contain a much more convenient way to design UITableView which includes the following improvements:
• Static UITableView (fixed number of cells and the cells do not change dynamically): It is now possible to create static UITableView and specify the number of sections and rows within Interface Builder. In addition, storyboards allow you to design each instance of UITableViewCell in the graphical editor and without writing a single line of code.
• Dynamic UITableView: the concept prototype cell was introduced to allow users to design custom cells in-place, which then can be replicated and managed in code. This helps keeping table-relevant pieces together inside the same UITableView (as the previous approach involved defining a single cell as a separate XIB file and subsequently get loaded into UITableViewController for constructing cells).
• Based on the arguments above, it is not hard to observe that storyboards simplify the process of setting up a working app with simple views and navigation. Storyboards should be regarded as a well-suited tool for prototyping and simple apps.
• Storyboards also bring performance benefits in terms of memory usage as each view controller is instantiated dynamically only when it is required.
These advantages are not obtained by free; there are certainly limitations and inconveniences that come with storyboards.
• Having multiple view controllers in one storyboard may be confusing and difficult to navigate to your targeted ones when there are too many scenes to fit on one monitor. Additionally, because storyboards are large files, they can be slow to load and merging in source control can be problematic and complex when multiple developers work on the same storyboard. When resolving conflicts, you will probably discover that the meaning of each line may be difficult to understand. In the example below, two developers have made change to the position of an item which results in the conflicting id attributes. However, the id itself doesn’t provide any meaningful indication about the change.
Example 1 An example of storyboard conflict
A partial solution to address reduced maintainability and increased complexity related to large storyboards is to consider modularise views into multiple storyboards where possible. As for XIB files, there is no limit to the number of storyboards a project can have.
• The reusability of storyboards is rather restricted. An individual view controller inside a storyboard cannot be exported reused elsewhere as a single entity.
• Storyboards are designed to handle the transitions between view controllers easily. However, passing data between view controllers has to be configured by code. This is done using prepareForSegue:sender: method, which is called before performing a segue/transition. The drawback with this approach is that we could potentially end up with a huge block of if/else-if statements to identify each segue by name which can be error prone.
• Another minor disadvantage is that storyboards are not compatible with pre iOS 5 versions. To sum up, the key points we need to consider before using storyboards are 1) size of your app -storyboards should be the recommend tool when it comes to small apps 2) number of developers in your team 3) dynamic or static views and reusability of views - dynamic or complicated layout is best-implemented using code and XIBs provide better reusability if we wish to share the same view design across multiple scenes.
Compared with storyboards, XIBs are the older way of designing iOS user interface. XIBs represent a single view element which contains items like button, labels and text fields. These views are often accompanied by their corresponding controller counterparts. This layout is slightly different from storyboards which include view controllers and associated views in the same scene. Modularity is a key aspect when it comes to XIB files. Although it is possible to contain several views and components in one single XIB file, it is common and considered as a good practice to contain a single view and avoid storing unrelated views within the same file. This helps maintaining the efficiency and responsiveness of your app. Here are the main features I would like to point out:
• Flexibility and reusability advantages have been mentioned in the previous section. Any arbitrary view component created using XIB can be applied to a view controller whenever needed. Hence XIBs should be used when storing views, custom controls and repeated views.
• XIBs are lazy loaded, which means they don’t use memory until they have to be loaded. However, the latency in the lazy loading process might be a downside as well and therefore keeping XIBs as slim as possible is desirable.
• Although XIBs suffer from the merge conflicts we discussed earlier, their smaller scale might migrate the risks some extend.
• XIBs are unable to capture the relationship between various screens. As a consequence, these transitions need to be specified by code, which could raise the complexity of your code and it might be confusing to follow the transition flow of the app.
• Lack of the ability to design cells in-place implies more effort is needed when dealing with tables comparing with storyboards.
The usage of handwritten coding to create all the graphical representations, layout and positioning is the other main approach in iOS UI development. Despite the fact that it might be time-consuming to develop and it carries increased code complexity, coding is still preferred by many developers, and here are some of their arguments:
• It promotes collaboration between developers as it is easier to understand and resolve merge conflicts.
• Creating views through code minimises dependencies on other tools such as storyboards and XIBs. It gives you more control and freedom. Moreover, designing user interface by raw code, it enhances developers’ understanding of how these components fit together and the process under the hood.
• In terms of performance, view creation by coding is faster than XIBs and storyboards as these graphical tools carry the extra overhead of loading and parsing.
• Code can be the only option at times when working with XIBs and storyboards is complicated or unfeasible. Typical examples are when graphical elements like tables need to be adjusted dynamically based on content.
• Due to the extra complexity in code, it is likely to be confusing for beginners to follow the app flow and navigation.
• It is hard to visualise your changes without compiling and running your app. Things like setting the layout/position of graphical components may take much longer without a graphical preview.
We can observe from the sections above that each of these approaches can bring benefits and simplification to your app design. Luckily, Xcode supports all three tools to be mixed and combined effectively in the same project. Here are the main requirements and factors we had to take into account when deciding whether to introduce storyboards into our project (we are not fanatics of pure programmatic UI design so this was not taken into account):
• As mentioned at the start of this post, the main task we faced was to redesign the test app by replacing rounded buttons with tables.
• Some of these new tables were static but some needed to be dynamic and grow/shrink based on the number of tickets.
• The test app was relatively simple with around 10 view controllers.
• Small team size with just one developer working on this redesign work.
• Given the time constraints, we might wish to reuse some of the old XIB views while adding storyboard for the main navigation and leave the rest of the XIB to storyboard transformation as a future task. So ensuring easy and efficient support for both XIBs and storyboards was an important aspect to consider.
Based on the theoretical investigations, storyboards should be used as the predominant tool to design our new test app. As the first step, I spent a day prototyping storyboard with the goals to understand the bullet points outlined above and at the end of that day, I was positively surprised about its efficiency and productivity when it comes to handling tables, transitions and also integration with XIBs. The efficiency improvements in managing tables were particularly observable compared with the previous days when I was dealing with tables using XIBs. The other two designing approaches are also deployed in our app. For example, a reusable custom UITableViewCell layout is stored as a XIB file and loaded dynamically based on the number of tickets required. Subsequently, the appearance of this dynamic table is updated accordingly, which is performed by programmatic interface design.
Storyboards add noticeable simplification to iOS interface design in many aspects but you might lose flexibility in comparison with the other two options. Although code tends to be flexible, sticking to it fanatically means you lose many features and automation storyboards and XIBs supply with. The correct usage of these tools is completely based on the context which includes but not limited to complexity, type, graphical components used in your app. With Xcode’s ability to combine all these method effectively in one single project, you should assess every option’s strengths and weaknesses and be encouraged to use the simplest concept that fits your needs and purposes.