iOS Developer Library

Developer

Start Developing iOS Apps Today

PDF
On This Page

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. 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:

  • Use storyboards to define app content and flow

  • 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:

image: ../Art/ios_simulator_nav_bar_2x.png

Create a Second Scene

So far, you’ve worked with a single scene managed by a view controller that represents a page where you can add an item to your to-do list: the add-to-do-item scene. 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 (UITableView) designed specifically to display a scrolling list of items.

To add a scene with a table view to your storyboard

  1. In the project navigator, select Main.storyboard.

    If the project navigator is still collapsed, toggle it by clicking the Navigator button in the Xcode toolbar.

    image: ../Art/toggle_navigator_utility_on_2x.png

    If the assistant editor is still open, return to the standard editor by clicking the Standard button.

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

  3. In the Object library, type table view controller in the filter field to find a Table View Controller object quickly.

  4. 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 zoom out using Editor > Canvas > Zoom.

    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 to-do list and one for adding to-do items.

image: ../Art/storyboard_table_view_2x.png

It makes sense to have the to-do 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

  • Drag the storyboard entry point from the add-to-do-item scene to the table view controller.

    image: ../Art/storyboard_entry_point_drag_2x.png

    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.

image: ../Art/ios_simulator_empty_table_view_2x.png

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

  1. If necessary, open the outline view image: ../Art/outline_view_toggle_2x.png.

  2. In the outline view, select Table View under Table View Controller.

  3. With the table view selected, open the Attributes inspector image: ../Art/inspector_attributes_2x.png in the utility area.

  4. 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.

  5. In the outline view, select the top cell.

    image: ../Art/table_view_top_cell_2x.png
  6. 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.

  7. In the outline view, select the label.

    image: ../Art/table_view_cell_label_2x.png
  8. In the Attributes inspector, change the text of the label from “Title” to “Mow the lawn.” For the change to take effect, press Return or click outside the utility area.

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

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

  10. 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.

(You might notice that the top cell is overlapped by the device’s status bar—the area that shows the time, battery level, and other information. Don’t worry, you’ll fix that next.)

image: ../Art/ios_simulator_static_table_view_2x.png

Add a Segue to Navigate Forward

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. As your learned in Defining the Interaction, 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

  1. In the outline view, select Table View Controller.

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

Xcode adds a new navigation controller to your storyboard, sets the storyboard entry point to it, and creates a relationship between the new navigation controller and your existing table view controller.

image: ../Art/storyboard_add_nav_controller_2x.png

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 storyboard entry point 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. The navigation bar extends its background to the top of the status bar, so the status bar doesn’t overlap with your content anymore.

image: ../Art/ios_simulator_static_table_view_with_nav_2x.png

Now, you’ll add a title (to the to-do list) and a button (to add additional to-do items) to the navigation bar. 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.

To configure the navigation bar in the table view controller

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

    image: ../Art/table_view_navigation_item_2x.png
  2. In the Attributes inspector, type To-Do List in the Title field. Press Return to save.

    Xcode changes the description of the scene from “Table View Controller Scene” to “To-Do List Scene” to make it easier for you to identify the scene. The description appears in the outline view.

    image: ../Art/table_view_named_2x.png
  3. In the Object library, find a Bar Button Item object.

  4. 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.

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

  6. 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.

image: ../Art/ios_simulator_nav_bar_2x.png

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. You need to configure the Add button to bring up another scene when a user taps the button.

To configure the Add button

  1. On the canvas, select the Add button.

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

    image: ../Art/drag_from_add_button_2x.png

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

    image: ../Art/action_segue_menu_2x.png

    The Action Segue menu allows you to choose what type of segue to use to transition from the to-do list to the add-to-do-item view controller when the user taps the Add button.

  3. Choose show from the Action Segue 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.

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 show segue, the backward navigation is handled for you. This means you can click the back button to get back to the table view.

image: ../Art/ios_simulator_navigation_2x.png

The push-style navigation you get by using the show segue 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 an 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.

Instead of deleting the existing segue and creating a new one, simply change the segue’s style in Attributes inspector. Like most selectable elements in a storyboard, you can edit a segue’s attributes using Attributes inspector.

To change the segue style

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

    image: ../Art/show_segue_2x.png
  2. In the Attributes inspector, choose Present Modally 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

  1. In the outline view, select View Controller.

  2. 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 Save. Later, you’ll link these buttons to actions.

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

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

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

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

    image: ../Art/view_controller_named_2x.png
  3. 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.

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

    The button text changes to “Save.”

  5. 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.

  6. 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-to-do-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, Save 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.

image: ../Art/ios_simulator_add_item_with_nav_2x.png

Create Custom View Controllers

You’ve accomplished all of this configuration without writing 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 the add-to-do-item view controller to correspond to the code in ViewController.h and ViewController.m in your project navigator. These files represent a custom view controller sublass that got created for in you as part of the Single View Application template. However, it’s important to learn how to create and configure custom classes on your own, because this is a common task in app development. So now, you’ll create a custom class called AddToDoItemViewController to correspond with the add-to-do-item scene in your storyboard. AddToDoItemViewController will subclass UIViewController so that it gets all of the basic view controller behavior.

(Go ahead and delete ViewController.h and ViewController.m if you’d like, because you won’t be using them. To delete a file from your project, select it in the project navigator, press the Delete key, and click Move to Trash in the message that appears.)

To create a subclass of UIViewController

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

  2. On the left of the dialog that appears, select Source under iOS.

    image: ../Art/add_new_file_2x.png
  3. Select Cocoa Touch Class, and click Next.

  4. In the Class field, type AddToDoItem.

  5. Choose UIViewController in the “Subclass of” pop-up menu.

    The class title changes to AddToDoItemViewController. Xcode makes it clear from the naming that you’re creating a custom view controller, so leave the new name as is.

    image: ../Art/create_new_vc_subclass_2x.png
  6. Make sure the “Also create XIB file” option is unselected.

  7. Make sure the Language option is set to Objective-C.

  8. Click Next.

    The save location defaults to your project directory.

    The Group option defaults to your app name, ToDoList.

    In the Targets section, your app is selected and the tests for your app are unselected.

  9. Leave these defaults as they are, and click Create.

    Xcode creates a pair of files that define the AddToDoItemViewController class: the interface file (AddToDoItemViewController.h), and the implementation file (AddToDoItemViewController.h).

Now that you’ve created a custom view controller subclass, you need to tell your storyboard to use it: you’ll switch the add-to-do-item scene from using the old ViewController class to the new AddToDoItemViewController class.

To identify AddToDoItemViewController as the class for the add-to-do-item scene

  1. In the project navigator, select Main.storyboard.

  2. If necessary, open the outline view image: ../Art/outline_view_toggle_2x.png.

  3. In the outline view, select View Controller under Add To-Do Item Scene.

  4. With the view controller selected, click the third icon from the left in the utility area to open the Identity inspector image: ../Art/inspector_identity_2x.png.

    The Identity inspector lets you edit properties of an object in your storyboard related to that object’s identity, such as what class the object belongs to.

    image: ../Art/identity_inspector_2x.png
  5. 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 first one in the list should be your custom view controller, AddToDoItemViewController.

  6. Choose AddToDoItemViewController to use it for this scene.

    image: ../Art/identity_inspector_change_class_2x.png

    Notice that Xcode changed the description of your add-to-do-item view controller from “View Controller” to “Add To-Do Item” in the outline view. Xcode interprets the name of the custom class to make it easier to understand what’s going on in the storyboard.

    image: ../Art/outline_view_name_change_2x.png

At runtime your storyboard will create an instance of AddToDoItemViewController, your custom view controller subclass. The add-to-do-item screen in the app will get the interface defined in your storyboard and the behavior defined in AddToDoItemViewController.m.

Now, create a custom class to correspond with the to-do list scene in your storyboard. Because the to-do list scene is a table view controller, this class should subclass UITableViewController. UITableViewController offers the same basic view controller behavior as UIViewController with a few specialized pieces just for table views.

To create a subclass of UITableViewController

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

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

    image: ../Art/add_new_file_2x.png
  3. Click Next.

  4. In the Class field, type ToDoList before ViewController.

  5. Choose UITableViewController in the “Subclass of” pop-up menu.

    The class title changes to ToDoListTableViewController. Leave that as is.

    image: ../Art/create_new_table_vc_subclass_2x.png
  6. Make sure the “Also create XIB file” option is unselected.

  7. Make sure the Language option is set to Objective-C.

  8. Click Next.

    The save location defaults to your project directory.

    The Group option defaults to your app name, ToDoList.

    In the Targets section, your app is selected and the tests for your app are unselected.

  9. Leave these defaults as they are, and click Create.

    Xcode creates a pair of files that define the ToDoListTableViewController class: the interface file (ToDoListTableViewController.h), and the implementation file (ToDoListTableViewController.h).

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

To identify ToDoListTableViewController as the class for the to-do list scene

  1. In the project navigator, select Main.storyboard.

  2. In the outline view, select Table View Controller under To-Do List Scene and open the Identity inspector image: ../Art/inspector_identity_2x.png in the utility area.

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

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

Create an Unwind Segue to Navigate Back

In addition to show 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 to the previous scene. You can use an unwind segue to navigate back from AddToDoItemViewController to ToDoListTableViewController.

To create an unwind segue, you first add an action method to the destination view controller (the view controller for the scene you want to unwind to). This method must return an action (IBAction) and take a segue (UIStoryboardSegue) as a parameter. Because you want to unwind back to the to-do list scene, you need to add an action method with this format to the ToDoListTableViewController interface and implementation.

To add an action method to ToDoListTableViewController

  1. In the project navigator, open ToDoListTableViewController.h.

  2. Add the following code on the line below @interface:

    1. - (IBAction)unwindToList:(UIStoryboardSegue *)segue;
  3. In the project navigator, open ToDoListTableViewController.m.

  4. Add the following code on the line below @implementation:

    1. - (IBAction)unwindToList:(UIStoryboardSegue *)segue {
    2. }

You can name the unwind action anything you want. Calling it unwindToList: makes it clear where the unwind will take you. For future projects, adopt a similar naming convention, one where the name of the action makes it clear where the unwind will go.

For now, leave this method implementation empty. Later, you’ll use this method to retrieve data from the AddToDoItemViewController to add an item to your to-do list.

To create the unwind segue, link the Cancel and Save buttons to the unwindToList: action. In your storyboard, you do this using the Exit icon in the dock of the source view controller, AddToDoItemViewController.

To link buttons to the unwindToList: action method

  1. In the project navigator, select Main.storyboard.

  2. On the canvas, Control-drag from the Cancel button to the Exit item at the top of the add-to-do-item scene.

    image: ../Art/cancel_to_exit_drag_2x.png

    If you don’t see the Exit item but instead see the description of the scene, zoom in using Editor > Canvas > Zoom until you see it.

    A menu appears in the location where the drag ended.

    image: ../Art/action_segue_menu_exit_2x.png
  3. Choose unwindToList: from the shortcut menu.

    This is the action you just added to the ToDoListTableViewController.m file. Now, when users tap the Cancel button, they will navigate back to the to-do list scene. At this point, unwindToList: will be called.

  4. On the canvas, Control-drag from the Save button to the Exit item at the top of the add-to-do-item scene.

    image: ../Art/save_to_exit_drag_2x.png

    A menu appears in the location where the drag ended.

    image: ../Art/action_segue_menu_exit_2x.png
  5. Choose unwindToList: from the shortcut menu.

    Now, when users tap the Save button, they will navigate back to the to-do list scene. At this point, unwindToList: will be called.

Notice that you used the same action for both the Cancel and the Save buttons. In the next tutorial, you’ll distinguish between the two different cases when you write the code to handle the unwind segue.

Checkpoint: Now, run your app. At launch, you see a table view—but there’s no data in it. You can click the Add button and navigate to the add-to-do-item scene from the to-do list scene. You can click the Cancel and Save buttons to navigate back to the to-do list scene.

So why doesn’t your data show up? Table views have two ways of getting data—statically or dynamically. When a table view’s controller implements the required UITableViewDataSource methods, the table view asks its view controller for data to display, regardless of whether static data has been configured in Interface Builder. If you look at ToDoListTableViewController.m, you’ll notice that it implements three methods—numberOfSectionsInTableView:, tableView:numberOfRowsInSection:, and tableView:cellForRowAtIndexPath:. You’ll be working with these methods in the next tutorial to display dynamic data.

Recap

At this point, you’ve finished developing the interface for your app. You have two scenes—one for adding items to your to-do list and one for viewing the list—and you can navigate between them. In the next module, you’ll implement the ability for users to add a new to-do item and have it appear in the list.