Tutorial: Storyboards This tutorial builds

Tutorial: Storyboards

This tutorial builds on the project you created in the first tutorial ( Tutorial: Basics ). You’ll put to use what you learned about views, view controllers, actions, and navigation. Following the interface-first design process, you’ll also create some of the key user interface flows for your ToDoList app and add behavior to the scene you’ve already created.

This tutorial teaches you how to:

Adopt Auto Layout to add flexibility to your user interface

Manage multiple view controllers

Add actions to elements in your user interface

After you complete all the steps in this tutorial, you’ll have an app that looks something like this:

Adopt Auto Layout

The add-to-do-item scene is configured to work in portrait mode because that’s how you created it. So what happens if a user rotates the device? Try it out by running your app in Simulator.

To rotate in iOS Simulator

Launch your app in iOS Simulator.

Choose Hardware > Rotate Left (or press Command–Left Arrow).

As you see, the text field doesn’t look quite right. It stops about halfway across the screen. The text field should stretch all the way across the screen, as it does in portrait mode. Fortunately, Xcode has a powerful built-in layout engine called Auto Layout. With Auto Layout you describe your intent for the positioning of elements in a scene and then let the layout engine determine how best to implement that intent. You describe your intent using constraints —rules that explain where one element should be located relative to another, or what size it should be, or which of two elements should shrink first when something reduces the space available for each of them. For the add-to-do-item scene, two sets of constraints are needed—one to position the text field and the other to set its size.

Setting these constraints can easily be accomplished in Interface Builder.

To position the text field using Auto Layout

In the project navigator, select Main.storyboard .

In your storyboard, select the text field.

On the canvas, Control-drag from the text field toward the top of the scene, ending in the empty space around the text field. This space is the text field’s superview.

A shortcut menu appears in the location where you release the drag.

Choose “Top Space to Top Layout Guide” from the shortcut menu.

A spacing constraint is created between the top of the text field and the navigation bar.

If a different shortcut menu appears, perhaps with a menu item such as “Leading Space to Container,” this is because instead of dragging vertically to the top of the screen, you dragged in a different direction. Xcode uses the direction you drag in as a way to understand what kind of constraints you’re trying to make, and it uses the start and end points of the drag to understand which objects are being related by the constraints. Go ahead and experiment with different dragging directions to see what constraints are available.

When you’re done experimenting, Control-drag from the text field to the right, ending in the superview, to create a “Trailing Space to Container” constraint.

Control-drag from the text field to the left, ending in its superview, to create a “Leading Space to Container” constraint.

These constraints specify that the distance between the edges of the text field and its superview shouldn’t change. This means that if the device orientation changes, the text field will automatically grow to satisfy these constraints.

Checkpoint: Run your app. If you rotate the device, the text field grows or shrinks to the appropriate size depending on the device’s orientation.

If you don’t get the behavior you expect, use the Xcode Auto Layout debugging features to help you. With the text field selected, choose Editor > Resolve Auto Layout Issues > “Reset to Suggested Constraints” to have Xcode set up the constraints described by the steps above. Or choose Editor > Resolve Auto Layout Issues > Clear Constraints to remove all constraints on the text view, and then try following the steps above again.

Although your add item scene doesn’t do much yet, the basic user interface is there and functional. Considering layout from the start ensures that you have a solid foundation to build upon.

Creating a Second Scene

So far, you’ve been working with a single scene managed by a view controller that represents a page where you can add an item to your to-do list. Now it’s time to create the scene that shows the entire to-do list. Fortunately, iOS comes with a powerful built-in class called a table view designed specifically to display a scrolling list of items.

To add a scene with a table view to your storyboard

In the project navigator, select Main.storyboard .

Open the Object library in the utility area. (To open the library with a menu command, choose View > Utilities > Show Object Library.)

Drag a Table View Controller object from the list and drop it on the canvas to the left of the add-to-do-item scene. If you need to, you can use the Zoom Out button in the lower right of the canvas to get enough space to drag it to.

If you see a table view with content and nothing happens when you try to drag it to the canvas, you’re probably dragging a table view rather than a table view controller. A table view is one of the things managed by a table view controller, but you want the whole package, so find the table view controller and drag it to the canvas.

You now have two scenes, one for displaying the list of to-do items and one for adding to-do items.

It makes sense to have the list be the first thing users see when they launch your app, so tell Xcode that’s your intent by setting the table view controller as the first scene.

To set the table view controller as the initial scene

If necessary, open the outline view using the button in the lower left of the canvas.

In the outline view, select the newly added table view controller.

With the table view controller selected, open the Attributes inspector in the utility area.

In the Attributes inspector, select the checkbox next to the Is Initial View Controller option.

Alternatively, you can drag the initial scene indicator from the add-to-do-item scene to the table view controller directly on the canvas.

The table view controller is set as the initial view controller in your storyboard, making it the first scene that loads on app launch.

Checkpoint: Run your app. Instead of the add-to-do-item scene with its text field, you should now see an empty table view—a screen with a number of horizontal dividers to separate it into rows, but with no content in each row.

Display Static Content in a Table View

Because you haven’t learned about storing data yet, it’s too early to create and store to-do items and display them in the table view. But you don’t need real data to prototype your user interface. Xcode allows you to create static content in a table view in Interface Builder. This makes it a lot easier to see how your user interface will behave, and it’s a valuable way to try out different ideas.

To create a static cell in your table view

In the outline view for your interface, select Table View under Table View Controller.

With the table view selected, open the Attributes inspector in the utility area.

In the Attributes inspector, choose Static Cells from the pop-up menu next to the Content option.

Three empty table view cells appear in your table view.

In the outline view or on the canvas, select the top cell.

In the Attributes inspector, choose Basic from the pop-up menu next to the Style option.

The Basic style includes a label, so Xcode creates a label with the text “Title” in the table cell.

In the outline view or on the canvas, select the label.

In the Attributes inspector, change the text of the label from “Title” to “Mow the Lawn.” For the change to take effect, press Enter or click outside the utility area.

Alternatively, you can edit a label by double-clicking it and editing the text directly.

Repeat steps 4–7 for the other cells, giving them text for other likely to-do items.

Create enough cells so that the items more than fill the screen. You can create new cells by copying and pasting them or by holding down the Option key when dragging a cell.

Checkpoint: Run your app. You should now see a table view with the preconfigured cells you added in Interface Builder. See how the new table view feels when you scroll it. Try rotating the simulated device—notice how the table view is already configured to lay out its contents properly. You get a lot of behavior for free by using a table view.

When you’re done, it’s time to provide a way to navigate from this table view, with its list of to-do items, to the first scene you created, where a user can create a new to-do item.

Add a Segue to Navigate Forward

You have two view controllers configured in the storyboard, but there’s no connection between them. Transitions between scenes are called segues .

Before creating a segue, you need to configure your scenes. First, you’ll wrap your to-do list table view controller in a navigation controller. Recall from Defining the Interaction that navigation controllers provide a navigation bar and keep track of the navigation stack. You’ll add a button to this navigation bar to transition to the add-to-do-item scene.

To add a navigation controller to your table view controller

In the outline view, select Table View Controller.

With the view controller selected, choose Editor > Embed In > Navigation Controller.

Xcode adds a new navigation controller to your storyboard, sets the initial scene to it, and creates a relationship between the new navigation controller and your existing table view controller. On the canvas, if you select the icon connecting the two scenes, you’ll see that it’s the root view controller relationship. This means that the view for the content displayed below the navigation bar will be your table view. The initial scene is set to the navigation controller because the navigation controller holds all of the content that you’ll display in your app—it’s the container for both the to-do list and the add-to-do-item scenes.

Checkpoint: Run your app. Above your table view you should now see extra space. This is the navigation bar provided by the navigation controller.

Now, you’ll add a title (to the to-do list) and a button (to add additional to-do items) to the navigation bar.

To configure the navigation bar

In the outline view or on the canvas, select Navigation Item under Table View Controller.

Navigation bars get their title from the view controller that the navigation controller currently displays—they don’t themselves have a title. You set the title using the navigation item of your to-do list (the table view controller) rather than setting it directly on the navigation bar.

In the Attributes inspector, type My To-Do List in the Title field.

If necessary, open the Object library.

Drag a Bar Button Item object from the list to the far right of the navigation bar in the table view controller.

A button containing the text “Item” appears where you dragged the bar button item.

In the outline view or on the canvas, select the bar button item.

In the Attributes inspector, find the Identifier option in the Bar Button Item section. Choose Add from the Identifier pop-up menu.

The button changes to an Add button ( + ).

Checkpoint: Run your app. The navigation bar should now have a title and display an Add button. The button doesn’t do anything yet. You’ll fix that next.

You want the Add button to bring up the add-to-do-item scene. The scene is already configured—it was the first scene you created—but it’s not connected to the other scenes. Xcode makes it easy to configure the Add button to bring up another scene when tapped.

To configure the Add button

On the canvas, select the Add button.

Control-drag from the button to the add-to-do-item view controller.

A shortcut menu titled Action Segue appears in the location where the drag ended.

This is how Xcode allows you to choose what type of segue should be used to transition from the to-do list to the add-to-do-item view controller when the user taps the Add button.

Choose “push” from the shortcut menu.

Xcode sets up the segue and configures the add-to-do-item view controller to be displayed in a navigation controller—you’ll see the navigation bar in Interface Builder.

At this point, you might notice a couple of warnings in your project. Go ahead and open the Issue navigator to see what’s wrong.

Because you added the add-to-do-item scene to the navigation stack, it now displays a navigation bar. This bar caused the frame of your text field to move down, which means that the Auto Layout constraints you specified earlier are no longer satisfied. Fortunately, this is easy to fix.

To update the Auto Layout constraints

In the outline view or on the canvas, select the text field.

On the canvas, open the Resolve Auto Layout Issues pop-up menu , and choose Update Constraints.

Alternatively, you can choose Editor > Resolve Auto Layout Issues > Update Constraints.

The constraints are updated and the Xcode warnings disappear.

Checkpoint: Run your app. You can click the Add button and navigate to the add-to-do-item view controller from the table view. Because you’re using a navigation controller with a push segue, the backward navigation is handled for you. This means you can click the back button to get back to the table view.

The push navigation is working just as it’s supposed to—but it’s not quite what you want when adding items. Push navigation is designed for a drill-down interface, where you’re providing more information about whatever the user selected. Adding an item, on the other hand, is a modal operation—the user performs some action that’s complete and self-contained, and then returns from that scene to the main navigation. The appropriate method of presentation for this type of scene is a modal segue.

To change the segue style

In the outline view or on the canvas, select the segue from the table view controller to the add-to-do-item view controller.

In the Attributes inspector, choose Modal from the pop-up menu next to the Style option.

Because a modal view controller doesn’t get added to the navigation stack, it doesn’t get a navigation bar from the table view controller’s navigation controller. However, you want to keep the navigation bar to provide the user with visual continuity. To give the add-to-do-item view controller a navigation bar when presented modally, embed it in its own navigation controller.

To add a navigation controller to the add-to-do-item view controller

In the outline view, select View Controller.

With the view controller selected, choose Editor > Embed In > Navigation Controller.

As before, Xcode adds a navigation controller and shows the navigation bar at the top of the view controller. Next, configure this bar to add a title to this scene as well as two buttons, Cancel and Done. Later, you’ll link these buttons to actions.

To configure the navigation bar in the add-to-do-item view controller

In the outline view or on the canvas, select Navigation Item under View Controller. If necessary, open the Attributes inspector .

In the Attributes inspector, type Add To-Do Item in the Title field.

Xcode changes the description of the view controller from “View Controller” to “View Controller – Add To-Do Item” to make it easier for you to identify the scene. The description appears in the outline view.

Drag a Bar Button Item object from the Object library to the far right of the navigation bar in the add-to-do-item view controller.

In the Attributes inspector, choose Done from the pop-up menu next to the Identifier option.

The button text changes to “Done.”

Drag another Bar Button Item object from the Object library to the far left of the navigation bar in the add-to-do-item view controller.

In the Attributes inspector, choose Cancel from the pop-up menu next to the Identifier option.

The button text changes to “Cancel.”

Checkpoint: Run your app. Click the Add button. You still see the add item scene, but there’s no longer a button to navigate back to the to-do list—instead, you see the two buttons you added, Done and Cancel. Those buttons aren’t linked to any actions yet, so you can click them, but they don’t do anything. Configuring the buttons to complete or cancel editing of the new to-do item—and bring the user back to the to-do list—is the next task.

Create Custom View Controllers

You’ve accomplished all of this configuration without needing to write any code. Configuring the completion of the add-to-do-item view controller requires some code, though, and you need a place to put it. Right now Xcode has configured both the add-to-do-item view controller and the table view controller as generic view controllers. To have a place for your custom code, you need to create subclasses for each of these view controllers and then configure the interface to use those subclasses.

First, you’ll address the add-to-do-item view controller scene. The custom view controller class will be called XYZAddToDoItemViewController. because this view controller will control the scene that adds a new item to your to-do list.

To create a subclass of UIViewController

Choose File > New > File (or press Command-N).

On the left of the dialog that appears, select the Cocoa Touch template under iOS.

Select Objective-C Class, and click Next.

The save location will default to your project directory. Leave that as is.

The Group option will default to your app name, ToDoList. Leave that as is.

The Targets section will default to having your app selected and the tests for your app unselected. That’s perfect, so leave that as is.

Now that you’ve created a custom view controller subclass, you need to tell your storyboard to use your custom class instead of the generic view controller. The storyboard file is a configuration of objects that’s used at runtime by your app. The app machinery is smart enough to substitute your custom view controller for the generic view controller the storyboard starts with, but you need to tell the storyboard that that’s what you want.

To identify your class as the view controller for a scene

In the project navigator, select Main.storyboard .

If necessary, open the outline view .

In the outline view, select the “View Controller – Add To-Do Item” view controller.

Click the disclosure triangle next to the “View Controller – Add To-Do Item” scene to show the objects in your scene. The first one should be the view controller. Click it to select it. Notice that the scene row has a different icon from the view controller row.

With the view controller selected, open the Identity inspector in the utility area.

The Identity inspector appears at the top of the utility area when you click the third button from the left. It lets you edit properties of an object in your storyboard related to that object’s identity, such as what class it is.

In the Identity inspector, open the pop-up menu next to the Class option.

You’ll see a list of all the view controller classes Xcode knows about. The last one in the list should be your custom view controller, XYZAddToDoItemViewController. Choose it to tell Xcode to use your view controller for this scene.

At runtime your storyboard will create an instance of XYZAddToDoItemViewController —your custom view controller subclass—instead of the generic UIViewController. Notice that Xcode changed the description of your add-to-do-item view controller scene from “View Controller – Add To-Do Item” to “Add To Do Item View Controller – Add To-Do Item.” Xcode knows that you’re now using a custom view controller for this scene, and it interprets the name of the custom class to make it easier to understand what’s going on in the storyboard.

Now, do the same thing for the table view controller.

To create a subclass of UITableViewController

Choose File > New > File (or press Command-N).

On the left, select Cocoa Touch under iOS, then select Objective-C Class. If you haven’t created any classes since the last steps in the tutorial, it’s probably already selected for you.

Click Next.

The save location will default to your project directory. Leave that as is.

The Group option will default to your app name, ToDoList. Leave that as is.

The Targets section will default to having your app selected and the tests for your app unselected. That’s perfect, so leave that as is.

Click Create.

Once again, you need to make sure to configure your custom table view controller, XYZToDoListTableViewController. in your storyboard.

To configure your storyboard

In the project navigator, select Main.storyboard .

If necessary, open the outline view.

In the outline view, select the table view controller and open the Identity inspector in the utility area.

In the Identity inspector, choose XYZToDoListTableViewController from the pop-up menu next to the Class option.

Now, you’re ready to add custom code to your view controllers.

Unwind a Segue to Navigate Back

In addition to push and modal segues, Xcode provides an unwind segue. This segue allows users to go from a given scene back to a previous scene, and it provides a place for you to add your own code that gets executed when users navigate between those scenes. You can use an unwind segue to navigate back from XYZAddToDoItemViewController to XYZToDoListTableViewController .

An unwind segue is created by adding an action method to the destination view controller (the view controller you want to unwind to). A method that can be unwound to must return an action ( IBAction ) and take in a storyboard segue ( UIStoryboardSegue ) as a parameter. Because you want to unwind back to XYZToDoListTableViewController. you need to add an action method with this format to the XYZToDoListTableViewController interface and implementation.

To unwind back to XYZToDoListTableViewController

In the project navigator, open XYZToDoListTableViewController.h .

Chick this out