Advertisement
iOS SDK

iOS 5 SDK: Storyboards

by

Storyboarding is one of the most exciting new features about the iOS 5 SDK. Take a look at the wealth of functionality offered by Storyboards in today's iOS 5 SDK tutorial!

The iOS 5 SDK comes with a lot of new API's to play with. iCloud is a great new interface for developers to use to make their application create the most seamless user experience possible. ARC presents a very fundamental shift in memory management throughout your applications. But arguably the most disruptive addition to the iOS 5 developer tool belt is Storyboarding. Storyboarding is big. It will change the way you write a majority of your interface code and also presents the potential to effect your development workflow as a whole throughout a team. Is storyboarding the right API for your next app? Should you upgrade your existing apps to use it? Let's dive into this new API some more and see what it has to offer.


Mile High Overview

Essentially, Storyboards are a new type of container available in Xcode to hold collections of NIB/XIB's. As a result, you may never need to use just an independent *.XIB file again (don't panic - they will still behave exactly as they have previously if you need to keep using them for now). Not only will a Storyboard file hold a collection of NIBs, but it will also allow you to visually control how those views will segue between each other. This means the entire flow of your app's interface can be modeled and visualized through your single storyboard file. Generally, interface flow requires the ability to get instances of controllers you want to flow to, send data to those instances, and then actually display those instances with some type of segue or transition. This is all very simple to do using Storyboarding, and using Storyboards instead of XIB files will let you cut a lot of code out of your projects. But Storyboarding doesn't stop there. Storyboarding can also enable you to create table view cells and table view controllers with simplicity. Let's take a look at how UIStoryboarding specifically addresses each of these use cases.


Compatibility Considerations

An important consideration before deciding to use Storyboarding is versioning. A project built with Storyboarding will be compatible with iOS 5 and greater. While you could build an app with Storyboarding and create proper checks to use other iOS 4 or prior friendly XIB's at certain places, that would be a lot of extra work for little pay off. If you are going to need to support releases prior to iOS 5, you should likely use the standard view controller and XIB method of UI development.


Sample Project Code

There is a sample project to accompany this article. You can grab it over at GitHub.


Scene Creation

All of UIStoryboards abilities are interconnected in one way or another, so deciding on a logical entry point to describe the objects is difficult. We will begin by looking at the new Storyboard layout interface and work forward from there. Below you will see an example of a UIStoryboard editor window within Xcode 4.2:

UIStoryboard Editor View Zoomed Out

Here you can clearly see that I have 6 different view controllers presented throughout the flow of the application. For consistency with the official Apple nomenclature, we will refer to each of the storyboard sections as a "scene". Some scenes will have *.h and *.m view controller files, and some are completely configured in Interface Builder. In the demo project, I present an initial scene that leads to 5 distinctly different scenes. I only have 3 explicitly defined UIViewController subclasses to cover all 6 scenes. This whole flow of moving scenes on and off screen can be composed from this Storyboard layout view. The picture above shows the zoomed out story board view. Here you can not move specific UIKit elements around on the views, but rather you are meant to organize the high level flow of your scenes. Once you have finished that, you can zoom in and begin to specify the details of each scene.

UIStoryboard Editor View Zoomed In

Table View Controllers Rebooted

View Controllers, especially table view controllers, can now be explicitly defined exclusively through Storyboarding. From now on, if you view controller or table view controller contains only static content you can choose to implement the entire thing through the Storyboard editor. Interface Builder's inspector panes have been updated with everything you need to define a static table view and design your table view cells. Below you can see a zoomed up image of the options to configure these static tables and cells through Interface Builder.

UIStoryboard Static Table View Configuration
UIStoryboard Static Table View Cell Configuration

Table View's now can be specified as static. This leads to an incredible savings of time if you have faced programmatically creating a complex table view of static data. Here is a screen shot of my static table view in my sample application. Any developer with extensive table view development experience can identify with how long this would have previously taken, but with Storyboarding it took me all of a few minutes.

Sample Application Static Table View

In order to facilitate this, all of the data source information we are so familiar with providing for table views is now visualized through the object hierarchy view in Interface Builder. This will represent all of your tables sections, cells and so on. Keeping an eye on this will let you understand how the WYSIWYG actions you are performing translate into the more traditional data inputs for table views.

Sample Application Static Table Interface Builder Object Hierarchy View

So, as you can see, there is tons of new stuff here! Many applications have non dynamic table views that have previously been implemented with distinct UITableViewControllers, but now you can do them all visually. Remember less code usually means less bugs. There is a lot more cool stuff to check out here with static table views, but we have a lot more to cover so let's move on.


Prototype Table View Cells

Of course you can use the classical UITableViewDataSource protocol methods to define a table views content programmatically. This will still likely be required for most of your table views. However, storyboards also offers some help here. Interface Builder now has much greater support for defining custom UITableViewCells visually. When you do this, you layout the UI elements in the cell as you would imagine, and the final step is to provide the table view cell with a reuseIdentifier.

Dynamic Table View Cell Definition

With this done you can get an instance of the table view cell by using the following for your tableView:cellForRowAtIndexPath: data source method:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"dyncamicCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {

        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
                                       reuseIdentifier:CellIdentifier] autorelease];
    }

    cell.textLabel.text = [NSString stringWithFormat:@"Section: %d Row: %d Sum: %d Product: %d", indexPath.section, indexPath.row, (indexPath.section+indexPath.row), (indexPath.section*indexPath.row)];

    return cell;
}

Navigating with Segues

So, besides all these beautiful static and dynamic view controllers, you can see I have arrows connecting all the scenes together. This is the second important piece to storyboarding. These arrows are new UIStoryboardSegue objects. These represent things like pushing view controllers onto navigation controller, presenting views modally, and whatever other kind of custom segue you can think of creating. The segues are as easy to implement as dragging a connection between two scenes. Any button or Gesture Recognizer (which by the way is also now configurable for views in IB, there is a ton of new stuff here!) can have a "push", "modal" or "custom" segue connection specified in the Storyboard. All of this is very simple to configure with the Storyboard editor, and you will get an end result that's something like this:

Hooking up a table view cell to a call a modal segue
Segue after it gets hooked up

So, all of this can be accomplished without writing any code. An interesting use case emerges with presenting scenes modally. When this happens, you are not provided a navigation controller back button by default, so you will need to have a regular IBAction to call when the scene should be dismissed. But in the case of modally presenting scenes through storyboarding, you do the following:

- (IBAction)done:(id)sender {
    [self dismissModalViewControllerAnimated:YES];
}

Despite the introduction of the presentingViewController property on UIViewControllers in iOS 5, when dismissing modal views that were presented by storyboarding, you call dismissModalViewControllerAnimated: on the modally presented view controller rather then on its parentViewController or presentingViewController.

If you want to dig deep into Storyboarding, you can look into creating your own custom UIStoryboardSegue. The subclassing of UIStoryboardSegue mostly involves overriding:

-(void)perform;

I have done a simple fade segue example with the sample project mentioned above. This is a somewhat unique class to subclass. From Apple's documentation, your responsibilities if you choose to do this are:

Regardless of how you perform the animation, at the end of it, you are responsible for installing the destination view controller (and its views) in the right place so that it can handle events.

You would probably use some core animation here, and no doubt we will see some interesting open source UIStoryboardSegue subclasses coming. I use a simple UIView helper method to perform a transition and on completion push the new view controller on the navigation controller with no animation. You can see code for the perform method below:

-(void)perform {

    __block UIViewController *sourceViewController = (UIViewController*)[self sourceViewController];
    __block UIViewController *destinationController = (UIViewController*)[self destinationViewController];                    

    [UIView transitionWithView:sourceViewController.navigationController.view
                      duration:.5
                       options:UIViewAnimationOptionTransitionCrossDissolve
                    animations:^{                        
                        [sourceViewController.navigationController pushViewController:destinationController
                                                                             animated:NO];
                    } 
                    completion:^(BOOL finished) {
                        NSLog(@"Transition Completed");
                    }];
}

Moving Data Between Controllers

Segues are also important for how you will pass data between these views. When presenting a view, the presenting view controller will have the method:

 (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

called. This is your opportunity to send data to the next view, The UIStoryboard segue delivered in the method signature above has a property called destinationViewController which you can pass data to. While this covers the concept of handing data to a view controller, passing data back is a bit more complicated. Apple has enforced using a protocol model. This would need to be done in code, where you would define a protocol in the top most view controller and have the view controller it is passing data back to implement it. This is one of the data passing use cases that has not been addressed by these enhancements to the IB editor, so you'll need to build this protocol manually.


Navigation Controllers Demystified

I have been doing iPhone development since before the SDK even supported Interface Builder. We're talking the very first release. And to this day, on Xcode 4.1 and prior, I would sometimes get confused on which XIB was supposed to hold my Navigation Controller and how I exactly set that up. Well it seems like Apple has heard the cries of developers on this, because there is now a new beautiful option to encompass view controllers in IB in Navigation Controller and Tab Bar Controllers. The new option is available in Editor -> Embed In -> Navigation Controller. You can see an image of the option below. When you have a view controller selected and select one of these options, Interface Builder will do the work for you of creating the appropriate holding container and injecting it with the view controller you have embedded within. This is one of my favorite new feature of the IDE because it represents Apple really starting to tailor Xcode for iOS development.

Menu to Embed View Controller In Navigation Controller and Tab Bar Controller

Team Workflow Disruption

The final possible effect Storyboarding could have in the coming years of team based iOS app development comes in how you can deliver components. Apple has shown examples of being delivered static libraries (.a files) from other teams and being able to drop in whole flowing sections of an application from these few very modular files. The pattern shown involves the bundle containing a compiled .a static library, a base view controller header file, and a .storyboard file. With these components you can now instantiate a new UIStoryboard from their storyboard file, pass data into the exposed base view controller, and then present it. The library delivered from the other team could have as many view controllers, web service interactions, or any other functional components, but the team using this code will only have to deal with 3 elements. With this approach being promoted by Apple, I wouldn't be surprised to see more developments in Xcode to endorse this type of workflow. If you are going to be working on a big modern app with a distributed team this could be valuable to consider!

Related Posts
  • Code
    iOS SDK
    Getting Started with UIKit Dynamics84oke preview image
    In the previous tutorial, I explained a few new features of iOS 7 that let you add subtle animations and greater interactivity with surprisingly little code to simulate real world physics. In this tutorial, I'll show you how to create a hidden form on a search results page.Read More…
  • Code
    iOS SDK
    Blocks and Table View Cells on iOS94dp7 preview image@2x
    A table view cell doesn't know about the table view it belongs to and that's fine. In fact, that's how it should be. However, people who are new to this concept are often confused by it. For example, if the user taps a button in a table view cell, how do you obtain the index path of the cell so you can fetch the corresponding model? In this tutorial, I'll show you how not to do this, how it's usually done, and how to do this with style and elegance.Read More…
  • Code
    iOS SDK
    Working with NSURLSession: Part 3E548b preview image@2x
    In the previous tutorials, we explored the fundamentals of the NSURLSession API. There is one other feature of the NSURLSession API that we haven't look into yet, that is, out-of-process uploads and downloads. In the next two tutorials, I will show you how to create a very simple podcast client that enables background downloads.Read More…
  • Code
    iOS SDK
    iOS Succinctly - Multi-Scene ApplicationsIos succinctly preview1
    The previous chapter introduced the basic workflow of iOS application development, but we worked within the confines of a single-view application. Most real-world applications, however, require multiple scenes to present data hierarchically. While there are many types of organizational patterns used for managing multi-scene apps, this chapter looks at one of the most common patterns: the master-detail application.Read More…
  • Code
    iOS SDK
    Implementing Container Containment - Sliding Menu ControllerViewcont 400x400
    In this tutorial, we'll implement a minimalistic version of the Facebook/Path-style UI. The objective will be to understand how to utilize view controller containment in order to implement custom flow in your app.Read More…
  • Code
    iOS SDK
    iOS SDK: Crafting Custom UITableView CellsStock xcode icon@2x copy
    A handful of predefined cell styles have been available to developers since iOS 3. They are convenient and very useful for prototyping, but in many situations you really need a custom solution tailored to the needs of the project you are working on. In this tutorial, I will show you how to customize table view cells by using static and prototype cells, and by subclassing UITableViewCell.Read More…