Sunday, June 10, 2012

Linking Storyboards

Summary

Previously I wrote about best practices with UIStoryboards. Since then I have continued to explore the possibilities of storyboards. With today being the eve of WWDC 2012, I wanted to share one of the tricks I have learned.

A key practice of storyboards is to break them down into natural, reusable modules. The downfall to this decomposition is when we need to transition from one storyboard to another. Storyboards were supposed to save us from the tedious transition code, but decomposition brings some of it back. Fortunately, there is a way to remove this pain.

Before I go into any details, I want to start with a disclaimer. I am not going to label this as best practice…at least not yet. All good design patterns need to stand the test of time. I have not used this trick enough to know if it works in all cases. Also, with this week being WWDC, Apple may expand UIStoryboards to include segues between storyboards.

Implementing

You should first download my code from GitHub. Following along will help in understanding how everything works.

The first thing to do is build your storyboards as you normally would. It's best if you break them down into natural modules. The rule of thumb is, if you can give each storyboard a meaningful name, then you have probably decomposed them well.

Now that you have your various storyboards, you can begin connecting them. To do this, you need to identify where you will transition into a different storyboard. At each of these points, create a blank UIViewController. This will represent the view in the other storyboard you will transition to.

Next you need to create a segue to each of these surrogate scenes. You can choose a Push, Modal, or custom segue according to your needs. They should look something like the picture below:



Once you have your surrogate scene in place, we can make the magic happen. We get to use a little-known tool of Interface Builder. It is the User Defined Runtime Attributes tool. This tool is hidden away in the Identity Inspector (3rd tab of the utility view). Up until now, you have probably used this inspector only to set a custom class. It also allows us to set the values of any property of any view we may be using in the storyboard.

First, we need to change the surrogate's class to RBStoryboardLink. Don't forget to include my RBStoryboardLink class in your app. Next, we can add a couple properties instructing the link what to transition to. The first, and required, attribute is "storyboardName" This is the name of the storyboard file you are going to transition to (without the .storyboard extension). The second attribute is optional. It called "sceneIdentifier". This is the UIStoryboard identifier you have given to a scene in the destination storyboard. If you ignore this attribute, then RBStoryboardLink will simply transition to the first scene in the storyboard. This is often what you want. Your Identity Inspector should now look something like the picture below:



Explanation

RBStoryboardLink works much like a symbolic link in your file system. A symbolic link essentially looks and acts like file. Likewise, RBStoryboardLink looks and acts much like a storyboard scene.

The idea behind RBStoryboardLink is simple. At a high level, it does the following:
  1. Creates the destination scene.
  2. Adds the view controller as a child of itself using the iOS 5 container API.
  3. Copies all the destination scene's properties into RBStoryboardLink.
Conclusion

RBStoryboardLink is a clean, easy-to-use technique to link storyboards without leaving Interface Builder. With WWDC this week, Apple may release similar functionality built directly into Interface Builder. If not, expect to use this technique frequently in your projects.