Introduction to iOS 5 Storyboards Part 2

Passing Data from One Screen to Another

This post continues from How To Use iOS 5 Storyboard Part 1 and uses the same project, StoryboardSample. Right now we have a two view controllers in our storyboard. When a user clicks on the button, the screen navigates to the second controller. Now we want to pass data from one scene to another using storyboards.

Passing Data From One Screen to Another

When a transition is happening from one scene to another, the storyboard runtime creates a segue object for that transition. A segue is an Objective-C object. It is an instance of class UIStoryboardSegue. A segue is represented in the Storyboard canvas.

When a transition happens, the current view controller will receive the prepareForSegue:sender: message where the prepareForSegue parameter will be an object of type UIStoryboardSegue. If you want to pass any data from the current view controller to view controller which is about to appear on the screen, you need to do that in the prepareForSegue:sender: method.

1. Add the following prepareForSegue:sender: method in the first view controller:

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    NSLog(@"Source Controller = %@", [segue sourceViewController]);
    NSLog(@"Destination Controller = %@", [segue destinationViewController]);
    NSLog(@"Segue Identifier = %@", [segue identifier]);
}

If you run this app now, you will see the results in the console window. However, the identifier variable is nil. Each segue has an identifier which can uniquely identify that segue.

Since one scene can have more than one segue associated with it, it is good to give your segues identifiers that you can then detect in your view controllers and take action accordingly.

A segue object in IB is the connection between two scenes as shown in Figure 1.

Segue arrow

Figure 1

Follow these steps to give your segue an identifier:

1. Select your segue object in IB
2. From the View menu, select Utilities->Show Attributes Inspector
3. In the Attributes Inspector, in the Identifier text field, write text for the identifier value for this segue. I named the identifier, SegueId1. Press Enter.

Also, add a second view controller to the project navigator. Follow the following steps to add a view controller to your existing project.

1, Go to File -> New -> New File. A New File dialog should appear as shown in Figure 2

Add New File dialog

Figure 2

2. Select Cocoa Touch under iOS on the left side and then select UIViewController subclass on the right.
3. Click Next and enter a Class name, I chose SecondViewController. Leave Targed for iPad and With XIB for user interface unchecked as shown in Figure 3

Name View Controller

Figure 3

4. Choose a folder to save new file and click Create button.

Your project navigator should contain similar files as shown in Figure 4

Project Navigator Files

Figure 4

You can see that when the storyboard runtime calls the prepareForSegue:sender: method in the current view controller to prepare it for the segue, the destination view controller has already been initialized in the segue object. Now this is your chance to pass any required data to the destination view controller, SecondViewController.

You can either set the data directly into a property of the destination view controller or pass your data by calling a method on that view controller. Below is the updated code to pass data from the first view controller to the second view controller. Add an import statement at the top of the implementation file of your first view controller to reference the second view controller as shown in Figure 5.

Import Statement

Figure 5

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    NSLog(@"Source Controller = %@", [segue sourceViewController]);
    NSLog(@"Destination Controller = %@", [segue destinationViewController]);
    NSLog(@"Segue Identifier = %@", [segue identifier]);

    if ([[segue identifier] isEqualToString:@"SimpleSegueToSecondViewController"])
    {
        SecondViewController *viewController = [segue destinationViewController];
        //viewController.dataModel = ...
    }
}


Adding a Storyboard to an Existing Project

If you already have an existing project where you navigate between screens manually and you want to start using storyboards, I will show how to take advantage of them with the below steps. The structure of project apps that use storyboards are different than project apps that do not. For once, the storyboard-based apps no longer use a main nib file for their windows. This needs to be removed from the .plist of our app. Also, when updating an old app to now use storyboards, you will need to make the app understand what storyboard files are by setting them in the .plist.

The last step below mentions to make sure that the app delegate in your app is not messing with how we are intending to load our storyboards. All apps are different, but you have to make sure that the app delegate is not assigning any object to the rootViewController property of the window. If it does, your storyboards will not be displayed and you will spend time trying to find out what the issue is.

1. From the File menu, choose New->New File
2. In the New File dialog, make sure you have selected User Interface under iOS on the left side and select Storyboard on the right.
3. Click Next to move to the next screen.
4. In this screen, pick the Device Family for which you want to create your storyboard. If your app is an iPhone or iPad only app, then pick the appropriate device family. If your app is a universal app, you will need to select one device family now, create the storyboard file and then come back and create another one for your other device family. Then press the Next button.
5. Now select where to save your storyboard file.
6. In the Project Navigator in Xcode, find the *Info.plist file. Note that this *.plist file might have been stored under a different name depending on the name of your project. Once you click on this file, the property list editor will open automatically as shown in Figure 6

Plist Editor

Figure 6

7. If you have any of the following keys, delete them from the *plist file: NSMainNibFile and NSMainNibFile~ipad
8. If you have an iPhone or iPad only app, then create a new key called UIMainStoryboardFile for iPHone or UIMainStoryboardFile~ipad for iPad. If you have a universal app, create both these keys.
9. For the value of these keys, provide the filename of the storyboards that you created without the .storyboard extension.
10. Make sure to save the .plist file.
11. Remove the application:didFinishLaunchingWithOptions: method from your app delegate’s implementation. Usually in this method, you write logic to set up different view controllers and windows and etc. With storyboards, you will no longer need this. At the very least, just remove the logic code in this method if you have any other code inside that remains relevant.

Introduction to iOS 5 Storyboards Part 1

I have been reading an early preview of iOS 5 Programming Cookbook and wanted to show a new feature called Storyboards. In previous versions of iOS, you would use navigation controllers to push and pop view controllers to be shown on the screen. Now in iOS 5, Apple believes this can be done easier with Storyboards. Soryboarding is the new way of defining the connection between different screens in your iOS app. For example, a nightmare before would be if you had 20 unique view controllers which you coded months ago, looking at the source code now you would have to spend time finding your way around the connection between these view controllers and what view controller is pushed when a certain action is taken by the user. This could become very difficult in keeping track on which view controllers are connected if you have not documented your code or created flow charts. Now with Storyboards, you can now view/create your entire app’s UI and the connection between each view controller in one screen using Interface Builder.

With storyboards, one screen’s worth of content is called a scene. A scene on the iPhone can be thought of as the view of a view controller, where you put all yoru contents on the screen to be presented to the user at the same time. On the iPad, more than one scene can be presented to the user at the same time because of the bigger screen. Storyboarding supports transitioning from one scene to another, similar to a navigation controller pushing a view controller on top of another. That is a transition. In order to explain Storyboards we will cover the following topics:

1. Creating a Project with Storyboards
2. Adding a Navigation Controller to a Storyboard
3. Passing Data from One Screen to Another
4. Adding a Storyboard to an Existing Project

Lets begin….

Creating a Project with Storyboards

I’m running the latest bits of Xcode which is v4.2.1 from Nov. 17, 2011 update on the AppStore. It includes many updates including iOS 5 SDK. With this new update, the New Project dialog has changed with new project such as Master-Detail Application, Single View Application, etc as shown in Figure 1.

1. Select Application on the left under iOS and on the right, select Single View Application and click Next button as shown in Figure 1.

New Project dialog

Figure 1

2. Name you project by filling in the Product Name field. I chose StoryboardSample. Also, make sure you check Use Storyboard and click Next button, as shown in Figure 2.

Name Project

Figure 2

3. Choose a folder location to save project and click Create button.

Since I created a project with Use Storyboard and Device Family = Universival, there are *_iPhone.storyboard and *_iPad.storyboard files that were added to the project as shown in Figure 3.

Storyboard Files

Figure 3

Adding a Navigation Controller to a Storyboard

Using the project created from the last section, you want to be able to manage multiple view controllers. In order to do that, you need to set a navigation controller as the initial view controller of your storyboard file. In previous iOS versions, we would create a view controller that would inherit from UINavigationController and set that class as the root view controller.

In order to add a navigation controller, simply follow these steps:

1. Select the iPhone storyboard in the Project Navigator in Xcode. For the StoryboardSample project, the file is MainStoryboard_iPhone.storyboard.

2. Once the storyboard file is selected in IB (Interface Builder), simply double-click on an empty space on the storyboard’s canvas and you will see the content shrink in size and give you more free space to play with, as shown in Figure 4. You can also you can the zoom in/out control in the bottom right of the canvas.

Default IB With View Controller

Figure 4

3. Under the View menu, select Utilities->Show Object Library

4. In the Object Library, find the Navigation Controller object and drag and drop it into the storyboard, to the left side of your existing view controller.

5. The navigation controller we just dragged on to the canvas already comes with a view controller of its own. We do not need this so go ahead and delete this view controller by selecting it first and then pressing the Delete button on the keyboard. Now we are left with only the navigation controller and our original view controller, as shown in Figure 5.

Navigation Controller With View Controller

Figure 5

6. Now we need to hook up the navigation controller with the view controller. Select the navigation controller object on the storyboard. Then, hold down the Control key and left button on your mouse and drag your mouse over to the view controller (on the right) that we had on our storyboard originally. This will draw a line from the navigation controller all the way to the view controller. Now release your mouse button and a Storyboard Segues pop-up will appear. Select Relationship – rootViewController. Now you will see a segue drawn from the navigation controller to the view controller, as shown in Figure 6.

Navigation Controller Connected With View Controller

Figure 6

7. All that is left is to make our navigation controller the initial/root view controller. To make our navigation the initial view controller, simply select the Navigation Controller under the Navigation Controller Scene panel in IB, as shown in Figure 7.

Navigation Controller Scene

Figure 7

8. Next, select the View menu in Xcode and choose View->Show Attributes Inspector. Once the attributes inspector is opened, under the View Controller category, check Is Initial View Controller checkbox, as shown in Figure 8.

Is Initial View Controller Property

Figure 8

Now if you run your application, you will notice that the initial view controller has a navigation bar on top, indication that this view controller now has a navigation controller, as shown in Figure 9.

iPhone Simulator

Right now we have a navigation controller with a view controller inside it. Now we want to trigger an action and then move from one view controller to another. In order to do that, let’s place a button on our view controller and push a view controller into the stack once the user presses the button.

9. Select MainStoryboard_iPhone.storyboard

10. In the Object Library, select View Controller object and drag and drop it onto the right side of our existing view controller on the storyboard, as shown in Figure 9.

Add Second View Controller

Figure 9

11. In Object Library, find the Button object and drag and drop it into the first view controller as shown in Figure 10. Note that if you are zoomed out, Interface Builder will not allow you to drop a button onto a view controller. You need to double click on an empty space on your storyboard to zoom into it before Interface Builder allows you to drop UI components onto your view controllers.

Add Button To View Controller

Figure 10

12. Now select the button, hold down the Control key on your keyboard and then hold down the left mouse button all the way while you drag to the second view controller.
13. Now lift your fingers off the mouse button and the Control key. A Storyboard Segues pop-up will appear. Select Push.

Now if you look at your storyboard, you will see the first view controller is connected to the second view controller.

Run the app and click on the button on the first view controller. You will see the second view controller will automatically get pushed onto the stack of view controllers. Once the second view controller is pressed, you will see a back button on the navigation bar. If you press that button, you will be send back to the first view controller, as shown in Figure 11.

Back Button

Figure 11

In Part 2 of this blog post, we will cover the last two sections: Passing Data From One Screen to Another and Adding A Storyboard To An Existing Project.

iOS 4 Persisting Data

I’m thinking of writing a very simple iOS app that has a login control. So a user can register or login with an existing account. While brain-storming how to approach this, I’ve looked in to SQLite that has been around for the longest time or using from the Cocoa Touch Library that was introduced in iOS 3, Core Data Framework. Currently I’m in the middle of researching the difference between the two. But I started thinking more and obviously I want my repository to be at a central location so multiple devices running my simple login app can access it.

Thus, I’m also looking into setting up a web service, perhaps a WFC service and throw it up on a web service I own. Then write some objective-c in my login app using NSURL, NSURLRequest and NSURLConnection classes. While scouring online, there’s a great SDK by Red Gate company, MobileFoo called iSQL SDK that allows you to retrieve data from a SQL Server at http://www.mobilefoo.com/ProductIndex.aspx. Look forward to a future blog post as I’ll play around with their SDK and see how seamless their wrapper classes allow me to hook up my login sample client app with a SQL Server database that will authenticate a user.

Understanding ViewControllers

Chapter 7 – View Controllers
To be honest, I quickly jumpted to Chapter 10, since that is the chapter to start working on the Homepwners application.  While only skimming through the previous chapters, I should of spent more time reading Chapter 7 on View Controllers.  So before I continue working on the next chapter on the Homepwners application, I would like to write a blog post on View Controllers.

Most iOS applications will need multiple “screens”.  In iOS development, each screen typically gets its own controller and XIB file.  Each controller has a view that gets placed on the winow.  Thus, we call these controllers, view controllers.  A view controller is a subclass of UIViewController and has an instance variable called, view.  And, we typically need an object to take care of the view swapping for us.  For this chapter, the example application will show the swapping is done by a UITabBarController. 

The iOS example application for this chapter contains two view controllers.  One displays the HypnosisView and the other will let the user get the current time by tapping a button.  The swapping of views uses the UITabBarController.

Now when creating views for the view controllers, there are two ways to do this: create the view programmatically or create a XIB file.  A good rule-of-thumb in deciding when to do one versus the other is if the view has no subviews, create it programmatically.  For Chapter 11 when we added a header control above the UITableView, we created a new viewcontroller and view.  If you remember, we created the view by creating a new XIB file made up of a UIView and 2 UIButtons, Edit and New.  We then made a action connection from each UIButton to the viewcontroller.  We then made a outlet connection from the FileOwner to the UIView control.  Then we load the XIB file manually using NSBundle in the viewcontroller by implementing headerView.  Reminder, XIB files are typically used to create the window and application delegate and to create the view for a view controller.

Chapter 7 helped me understand viewcontrollers much more in depth.  Stay tune for more implementation on the Homepwner class.

iOS development Part 2 – Editing UITableView

In the last blog post and last chapter (Chapter 10) of the Big Nerd Ranch iOS book, I created an application that displays a list of Possession items in a UITableView control.  I will add the source code and any gotchas I went through in that blog post in a little bit.  For this blog post, we will learn how to edit the content (Possession items) in a UITableView.  The UITableView has an editing property which allows you to move, delete and insert rows.  However, editing mode does not allow the user to edit the content of a row, the description property of the Possession item.

When in editing mode, a header view will appear about the UITableView that consists of 2 buttons, Edit and Add buttons.  Tapping the Edit button will toggle the editing mode of the UITableView.  Tapping the Add button will allow you to add a new Possession item to the UITableView.  Along with the 2 buttons in the HeaderView, there will be a delete button to the left of each row in the UITableView.  After this chapter, that will be all for the UITableView control and on to the UINavigationController control.  Stay tuned for an update with source code and gotchas I went through in implementing the edit functionality for the UITableView.

Part 1: UITableView and UITableVIewController

Part 2: Editing UITableView (current)

Part 3: UINavigationController

Part 4: Camera

Part 5: UIPopoverController and Modal View Controllers

Part 6: Saving, Loading and Multitasking

Part 7: Subclassing UITableViewCell

Part 8: Core Data

Part 9: Localization

iOS development Part 1 – UITableView and UITableViewController





I’ve been learning off and on iOS development by reading two main books, Xcode 4 iOS Development Beginner’s Guide (http://www.amazon.com/Xcode-iOS-Development-Beginners-Guide/dp/1849691304) and iOS Programming The Big Nerd Ranch Guide (http://www.amazon.com/iOS-Programming-Ranch-Guides-ebook/dp/B004Z2NQJQ).  I plan to start a series of blog posts to document what I’ve learned and for others to gain insight as well.  So far in reading a little from both books, they each have very simple sample projects to get your feet wet in learning how Xcode IDE is used, writing objective-c code and MVC design pattern.  Today, I’m going to focus on a more complex and realistic sample application that in the Big Nerd Ranch book.

The sample application starts off in Chapter 10, UITableView and UITableViewController, called Homepwner that basically keeps an inventory of all your possessions.  In the case of a fire or other catastrophe, you’ll have a record for your insurance company.  The Homeowner application will grow over the course of 9 chapters in the book.  The first chapter, Chapter 10, will present a list of Possession objects in a UITableView.  So keep coming back to this blog to follow the progression or leave comments if you have a copy of the Big Nerd Ranch and want to develop along with me through the 9 chapters. 

Part 1: UITableView and UITableVIewController (current)

Part 2: Editing UITableView

Part 3: UINavigationController

Part 4: Camera

Part 5: UIPopoverController and Modal View Controllers

Part 6: Saving, Loading and Multitasking

Part 7: Subclassing UITableViewCell

Part 8: Core Data

Part 9: Localization