Beginning Storyboards in iOS 5 Part 1
Update 10/24/12: If you’d like a new version of this tutorial fully updated for iOS 6 and Xcode 4.5, check out iOS 5 by Tutorials Second Edition! Note from Ray: This is the second iOS 5 tutorial in the iOS 5 Feast! This tutorial is a free preview chapter from our new book iOS 5 […] By Ray Wenderlich.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Beginning Storyboards in iOS 5 Part 1
45 mins
Update 10/24/12: If you’d like a new version of this tutorial fully updated for iOS 6 and Xcode 4.5, check out iOS 5 by Tutorials Second Edition!
Note from Ray: This is the second iOS 5 tutorial in the iOS 5 Feast! This tutorial is a free preview chapter from our new book iOS 5 By Tutorials. Matthijs Hollemans wrote this chapter – the same guy who wrote the iOS Apprentice Series. Enjoy!
This is a post by iOS Tutorial Team member Matthijs Hollemans, an experienced iOS developer and designer.
Storyboarding is an exciting new feature in iOS 5 that will save you a lot of time building user interfaces for your apps. To show you what a storyboard is, I’ll let a picture do the talking. This is the storyboard that we will be building in this tutorial:
You may not know exactly yet what the app does but you can clearly see which screens it has and how they are related. That is the power of using storyboards.
If you have an app with many different screens then storyboards can help reduce the amount of glue code you have to write to go from one screen to the next. Instead of using a separate nib file for each view controller, your app uses a single storyboard that contains the designs of all of these view controllers and the relationships between them.
Storyboards have a number of advantages over regular nibs:
- With a storyboard you have a better conceptual overview of all the screens in your app and the connections between them. It’s easier to keep track of everything because the entire design is in a single file, rather than spread out over many separate nibs.
- The storyboard describes the transitions between the various screens. These transitions are called “segues” and you create them by simply ctrl-dragging from one view controller to the next. Thanks to segues you need less code to take care of your UI.
- Storyboards make working with table views a lot easier with the new prototype cells and static cells features. You can design your table views almost completely in the storyboard editor, something else that cuts down on the amount of code you have to write.
Not everything is perfect, of course, and storyboards do have some limitations. The Storyboard Editor isn’t as powerful as Interface Builder yet, there are a few things IB can do that the Storyboard Editor unfortunately can’t. You also need a big monitor, especially when you write iPad apps!
If you’re the type who hates Interface Builder and who really wants to create his entire UI programmatically, then storyboards are probably not for you. Personally, I prefer to write as little code as possible — especially UI code! — so this tool is a welcome addition to my arsenal.
You can still use nibs with iOS 5 and Xcode 4.2. Using Interface Builder isn’t suddenly frowned upon now that we have storyboards. If you want to keep using nibs then go right ahead, but know that you can combine storyboards with nibs. It’s not an either-or situation.
In this tutorial we’ll take a look at what you can do with storyboards. The app we’re going to build is a bit pointless but it does show how to perform the most common tasks that you will be using storyboards for.
Getting Started
Fire up Xcode and create a new project. We’ll use the Single View Application template as our starting point and then build up the app from there.
Fill in the template options as follows:
- Product Name: Ratings
- Company Identifier: the identifier that you use for your apps, in reverse domain notation
- Class Prefix: leave this empty
- Device Family: iPhone
- Use Storyboard: check this
- Use Automatic Reference Counting: check this
- Include Unit Tests: this should be unchecked
After Xcode has created the project, the main Xcode window looks like this:
Our new project consists of two classes, AppDelegate and ViewController, and the star of this tutorial: the MainStoryboard.storyboard file. Notice that there are no .xib files in the project, not even MainWindow.xib.
Let’s take a look at that storyboard. Click the MainStoryboard.storyboard file in the Project Navigator to open the Storyboard Editor:
The Storyboard Editor looks and works very much like Interface Builder. You can drag new controls from the Object Library (see bottom-right corner) into your view controller to design its layout. The difference is that the storyboard doesn’t contain just one view controller from your app, but all of them.
The official storyboard terminology is “scene”, but a scene is really nothing more than a view controller. Previously you would use a separate nib for each scene / view controller, but now they are all combined into a single storyboard.
On the iPhone only one of these scenes is visible at a time, but on the iPad you can show several at once, for example the master and detail panes in a split-view, or the content of a popover.
To get some feel for how the editor works, drag some controls into the blank view controller:
The sidebar on the left is the Document Outline:
In Interface Builder this area lists just the components from your nib but in the Storyboard Editor it shows the contents of all your view controllers. Currently there is only one view controller in our storyboard but in the course of this tutorial we’ll be adding several others.
There is a miniature version of this Document Outline below the scene, named the Dock:
The Dock shows the top-level objects in the scene. Each scene has at least a First Responder object and a View Controller object, but it can potentially have other top-level objects as well. More about that later. The Dock is convenient for making connections. If you need to connect something to the view controller, you can simply drag to its icon in the Dock.
Note: You probably won’t be using the First Responder very much. This is a proxy object that refers to whatever object has first responder status at any given time. It was also present in Interface Builder and you probably never had a need to use it then either. As an example, you could hook up the Touch Up Inside event from a button to First Responder’s cut: selector. If at some point a text field has input focus then you can press that button to make the text field, which is now the first responder, cut its text to the pasteboard.
Run the app and it should look exactly like what we designed in the editor:
If you’ve ever made a nib-based app before then you always had a MainWindow.xib file. This nib contained the top-level UIWindow object, a reference to the App Delegate, and one or more view controllers. When you put your app’s UI in a storyboard, however, MainWindow.xib is no longer used.
So how does the storyboard get loaded by the app if there is no MainWindow.xib file?
Let’s take a peek at our application delegate. Open up AppDelegate.h and you’ll see it looks like this:
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
It is a requirement for using storyboards that your application delegate inherits from UIResponder (previously it used to inherit directly from NSObject) and that it has a UIWindow property (unlike before, this is not an IBOutlet).
If you look into AppDelegate.m, you’ll see that it does absolutely nothing, all the methods are practically empty. Even application:didFinishLaunchingWithOptions: simply returns YES. Previously, this would either add the main view controller’s view to the window or set the window’s rootViewController property, but none of that happens here.
The secret is in the Info.plist file. Click on Ratings-Info.plist (it’s in the Supporting Files group) and you’ll see this:
In nib-based projects there was a key in Info.plist named NSMainNibFile, or “Main nib file base name”, that instructed UIApplication to load MainWindow.xib and hook it into the app. Our Info.plist no longer has that setting.
Instead, storyboard apps use the key UIMainStoryboardFile, or “Main storyboard file base name”, to specify the name of the storyboard that must be loaded when the app starts. When this setting is present, UIApplication will load the MainStoryboard.storyboard file and automatically instantiates the first view controller from that storyboard and puts its view into a new UIWindow object. No programming necessary.
You can also see this in the Target Summary screen:
There is a new iPhone/iPod Deployment Info section that lets you choose between starting from a storyboard or from a nib file.
For the sake of completeness, also open main.m to see what’s in there:
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char *argv[])
{
@autoreleasepool {
return UIApplicationMain(argc, argv, nil,
NSStringFromClass([AppDelegate class]));
}
}
Previously, the last parameter for UIApplicationMain() was nil but now it is NSStringFromClass([AppDelegate class]).
A big difference with having a MainWindow.xib is that the app delegate is not part of the storyboard. Because the app delegate is no longer being loaded from a nib (nor from the storyboard), we have to tell UIApplicationMain specifically what the name of our app delegate class is, otherwise it won’t be able to find it.