Even after learning Objective-C and the basic design philosophy of Apple’s API it can still be difficult to get your head around the monster that is UIKit. Apple’s documentation tends to focus on the generailty of the APIs and not on how you might actually get something done. After some time, you will probably appreciate this generality, but in the beginning it can be quite daunting. In this tutorial we’ll see how to create an application that uses a UITabBarController. There will be a second tutorial tomorrow that covers UINavigationControllers using the same project.
By now you should have an understanding about the relationship between UIViewControllers and UIViews. UIViews encapsulates code that handles drawing. UIViews also capture user events, this is because UIView is a subclass of NSResponder (the base class for handling events). For example UIButton is a subclass of UIView. All UIButtons really do is draw their contents and handle events, by themselves they don’t actually do anything. Any application specific functionality related to a view should live inside of a UIViewController. If a user clicks on on a UIButton, the UIButton will check to see if it has a target method to call on some other object (a controller). In Interface Builder when you drag from a UIButton instance to a controller object in the nib file and select a method, you are selecting the button’s target for a particular user event. The controller will do all the work, the UIButton in this case is way for the controller to know when it should do something.
So lets create an application and explore how this works in practice. Launch XCode and create a new project, select the UITouch Window-Based-Application. Let’s call this project ViewControllerFun. Once the project has loaded, open up the MainWindow.nib in the Resources group folder by double-clicking on it. Interface Builder will launch.
Open the Library window and search for UITabBarController. This is a basic tab controller object, you don’t need to write any code to use it. Drag an instance into the nib window. Your nib window should look like this:
There are three different views onto your nib file, similar to the kinds of the views you can get in the Finder. The default one is the icon view- a lot of structure is invisible in this view. The second is a list view and the last one is a multi-column view. Select the list view, you see that some items now have disclosure triangles and you can look at the contents of the items in your nib file.
As you can see there are placeholder UIViewControllers inside the Tab Bar Controller! Double click on the Tab Bar Controller instance. A window representing what the Tab Bar Controller instance will open up. Double click on the first tab button and change it’s title to be First View, do the same for the second tab button but call it Second View. You screen should now look like the following:
Run the simulator from Interface Builder with Command-R. The Simulator should load showing your new tab bar view. Great!
Now switch back to XCode, and try to run your app. The Simulator will launch your app but this time you probably won’t see anything. Hmm. Something is wrong. Maybe you noticed that no where did we connect a view to a view controller as we have learned to do from the previous tutorials. At this point, your application does not know that it needs to display the contents of the tab bar controller. Let’s remedy that now.
Open the header files for ViewControllerFunAppDelegate in XCode. Make the interface portion look the following:
@interface ViewControllerFunAppDelegate : NSObject { IBOutlet UITabBarController *tabBarController; UIWindow *window; } @property (nonatomic, retain) IBOutlet UIWindow *window; @end
Here we’re saying that we’re going to connect our application’s delegate class to a UITabController that can be found in our nib file. We haven’t done this yet. Remember that the application delegate is simply a class that holds the high level logic of your application. Now make the implementation file look like the following:
@implementation ViewControllerFunAppDelegate @synthesize window; - (void)applicationDidFinishLaunching:(UIApplication *)application { [window addSubview:tabBarController.view]; // Override point for customization after application launch [window makeKeyAndVisible]; } - (void)dealloc { [window release]; [super dealloc]; } @end
Once we actually connect the tabBarController outlet in Interface Builder, this code ensures that when the app launches, the main window will show the contents of the tabBarController. Let’s do that now. Switch back to Interface Builder and right click on the View Controller Fun App Delegate, you’ll see the object connection window open. Drag from the tabBarController outlet to the Tab Bar Controller instance you added to the nib file. Save your nib file and switch back to XCode and run your application. It should now look like the following:
That wasn’t so hard. By now it should become clear that without setting up the view outlet of a UIViewController or programmatically adding a subview to the application’s window you will not see anything show up on the screen.
At this point you have a tab view in an application that doesn’t visibly show two different view. In Interface Builder make sure that you are looking at the MainWindow nib file with the list view selected. Open up the contents of the Tab Bar Controller instance. Note again that the Tab Bar Controller has two view controllers embedded in by default. Select the view controller for the first view. Open up the Inspector window and make sure the first tab of the Inspector window is selected. Notice that the there are two fields:
The interesting one is NIB Name. You can actually embed a reference to another nib file that will provide the contents of the view! Let’s do that now.
Switch back to XCode and add two new files to your project, both of them subclasses of UIViewControllers, one called MyFirstViewController and the other called MySecondViewController. We’re not going to put any logic into these, that will come in the next tutorial. Let’s also create the nib files for these new view controllers, with XCode add two more files to your project. When the new file dialog window comes up, make sure you select the User Interfaces list, you want both of these to be View Xib files, call them MyFirstView and MySecondView respectively.
Now switch back to Interface Builder, we going to have our Tab Bar Controller load these nib files for us. Select the first view controller in the MainWindow.xib window (make sure the nib window is in List mode, click the disclosure triangle next to Tab Bar Controller to see the view controller placeholders inside). Open the Inspector window. In the NIB Name field type MyFirstView (it should autocomplete). Do the same for the second view. The interface window for Tab Bar Controller should now look something like the following:
Lets edit these two new nibs so they are set up properly. From XCode open up MyFirstView.xib. Select File’s Owner and open up the Inspector window and select the last tab. We need to tell Interface Builder that the class that will control this nib is the MyFirstViewControoler UIViewController that we created using XCode. Then connect the view outlet of File’s Owner to the view in the MyFirstView nib window. Double click on the view to open it for editing and drop a UILabel in the center with the text “First View”. Save the nib file.
Repeat this entire process for MySecondView with appropriate name changes. Make sure you have saved your nib files and try running your application now from XCode. Your app should launch and you should be able to switch between the two different tabs and see that the different views load just fine.
Tomorrow you’ll convert one of the view to use UINavigationController.





