2.6. Designing a UI

There are two good reasons to build your first UI from scratch. The first is to get a feel for how Interface Builder works. The second is to visualize how the different components of a user interface fit together. There are windows, view controllers, data views, input controls, and a host of relationships that tie them all together. In this section, you'll build a simple interface from scratch and install it into a sample application.

Launch Interface Builder and edit the MainWindow template created with your window-based application. Your document window will contain a barebones template with only a window object.

2.6.1. The Window

The window object is the primary surface to which you'll attach your view controller. The window represents space on the iPhone's physical screen.

Select the Window icon in the document window and open the inspector by either pressing Command-1 or selecting Inspector from the Tools menu. The inspector will present you with options to change the color of the status bar within your application, the window transparency, the background color, and other window properties. If your application will use multi-touch gestures, they can be enabled here as well.

2.6.2. The View Controller

Drag a Tab Bar Controller into the document window. The Tab Bar Controller is a type of view controller that provides a series of tabs across the bottom of the window. The user can then click different tabs to display the various views your application supports. After dragging the controller into your document window, you will see a corresponding icon added to your template. Double-click the icon and a new window will appear containing two tabs and a gray window with the text View appearing in the middle. The buttons represent your tab bar, while the gray window represents the first page of your application's view.

If you hover over the name of a tab, you can click to rename the tab. Alternatively, you can select from a list of preset tabs by clicking a button tab and opening the inspector. From within the inspector, you'll be able to set the identifier of the button tab, such as Recents, History, etc. You can also define your own identifier. The identifier will identify the tab so that your code can reference it. You can also add a custom image to the button and adjust its size. Use the inspector to set up both button tabs.



Many of the properties you're able to set using Interface Builder are reproducible in code. Think of Interface Builder as a GUI for code. While Interface Builder supports many of the same characteristics you can set up in code, it does not support all. You'll start learning about the code side of these objects in Chapter 3.

You're finished with the controller view and window objects for now. Save the template with the name MainWindow. You'll come back to it later to make some final changes.


So far you've set up the button tabs in your controlling view, and you are now ready to create the two individual views to coincide with each button. To keep your interfaces modular, we suggest that you create a separate view class to correspond to each tab, and use a different Interface Builder file to describe each. You'll store the actual Interface Builder template for the view in a separate file, and it will be automatically loaded when the user switches tabs.

Create a new Cocoa Touch View template. Unlike the application template, this template includes a view class object rather than a window object. This view represents what is displayed to the user when he clicks the first tab.

In the library window, scroll down to the Data Views section and drag a Table View object onto your view. Ensure it is centered at the top of the window and sized to use the entire screen. Click the table and open the inspector. Here, you'll be able to change many different properties pertaining to the look and behavior of the table. When you are satisfied, save this file with the name Recents.

Create a second Cocoa Touch View project and, this time, drag a text view into the window. After customizing the text view's properties in the inspector, save this file with the name History.

2.6.4. Connecting the Views

You've now created a window, a controlling view, and two data views to display data in. Now all that's left is to connect the controlling view to the individual data views so that each will be displayed appropriately whenever the user taps the corresponding button.

Open your MainWindow template. Click the first tab to make it the active tab. Now click the grayed portion of the window labeled View. Open the inspector and enter the filename Recents in the field titled NIB Name, without an extension. The gray view window should now read "(Loaded from Recents.nib)." Now click the second tab and do the same thing, using the filename History. Your resulting template should look similar to the example in Figure 2-3.

Figure 2-3. A configured tab bar view controller

2.6.5. Adding Linkage to Code

Once you've finished editing, you'll need to add the two newly created files, Recents.xib and History.xib, to the Xcode project. Drag them into the Resources folder in your project and follow the prompts to add them as resources.

If you take a look at prototype for a project's application delegate class, you'll find a series of properties using the IBOutlet directive. This directive alerts Interface Builder to the presence of outlets in your code, so it can link the Interface Builder objects with the variable names specified in your codeā€”in this case, window and viewController:

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet RootViewController *viewController;

Inside your delegate class, the window, view controller, and any other objects you've created with Interface Builder are synthesized from the templates you've assigned in your NIB file:

@synthesize window;
@synthesize viewController;

The synthesize directive builds the necessary linkage from Interface Builder into the properties representing the objects in your code, and can be accessed as variables in your class. Internally, they are treated as if they were variables you created yourself:

[ window addSubview: viewController.view ];
[ window makeKeyAndVisible ];

Externally, any other class containing a pointer to the class can reference them:

MyAppDelegate *appDelegate;
[ appDelegate.window addSubview: appDelegate.viewController.view ];

The objects from the main template will be loaded in this fashion when the application launches, but you can also instantiate some objects directly from within your code. To create a new view controller object, for example, include a template named MyController.xib by adding it to your project's Resources folder. Instantiate the class using the UIViewController class's initWithNibName method:

MyApplicationViewController *myViewController = [
    [ MyViewController alloc ]
    initWithNibName: @"MyController"
    bundle: nil

You'll be able to access the variable in the same fashion as your synthesized objects:

[ window addSubview: myViewController.view ];

You'll learn more about creating and working with view controller classes in Chapter 3.