Creating Table Views and Navigation Controllers
If you want a table view to provide the main interface and navigation for your application in the same style as the contacts or settings apps, you need to implement a navigation controller along with a table view controller. Since the table view controller will display a table full screen, you don’t need to define a nib file for this view controller but instead configure everything through code, which isn’t as difficult as it sounds. Let’s look at how to add a navigation controller plus table view controller to an empty application.
- Start by creating a new X-Code project using the Empty Application template.
- Create a new file (File > New > File…)
- Make sure Cocoa Touch is highlighted in the iOS section on the left, select Objective-C Class and click Next.
- Give it a name and make it a subclass of UITableViewController. Make sure you un-select the With XIB for user interface check box before clicking Next again.
- Save the file in your project folder.
- Take a look at the header and implementation files for the new view controller and you’ll see that it’s already setup to display a table, what we need to do now is to load it and your navigation controller from the application delegate.
- Open the appDelegate header file.
- At the top, directly under the existing import command, add an import command for the root view controller’s header file. declare the navigation controller and define a property for it. Your appDelegate.h file should now look like:
- Switch to the appDelegate.m file.
- Add the @synthesize command for the navigation controller property (remember to release it if not using ARC).
- Find the – (BOOL)application:(UIApplication *) didFinishLaunchingWithOptions method which should look something like:
- Remove the self.window.backgroundColor line and replace it with the following lines:
- rootViewController *rootViewController = [[[rootViewController alloc] initWithStyle:UITableViewStylePlain]<autorelease>];
- UINavigationController *aNavigationController = [[[UINavigationController alloc] initWithRootViewController:rootViewController]<autorelease>];
- self.navigationController = aNavigationController;
- [self.window addSubview:[self.navigationController view]];
- Remember that autorelease is required for both the rootViewController and navigationController if you’re not using ARC. The screen shot below is using ARC, whilst the example above is not.
- The top part of your appDelegate.m file should now look like:
- If you want to use the grouped table style, change the rootViewController initWithStyle to initWithStyle:UITableViewStyleGrouped.
- Test your app by setting up an array in the root view controller and using that to populate the table, I’ve used the months array from my previous post.
Configuring The Detail View Controller
In this following example, I’m going to use the same detail view controller to display the detail info for each table cell, and that info is simply going to be the name of the month and number of days. You can easily use a different view controller for specific table cells if you wish and I’ll give a quick example of this at the end.
- Create a new file in your project for your detail view controller, make it a subclass of UIViewController and also create a nib file for simplicity.
- Open up the XIB file in Interface Builder and add two labels, one to display the month name and another to display the number of days.
- Open the detailViewController.h file and add properties for both the labels, along with a property to hold the month string that we’ll be passing from the rootViewController. We’ll also define a dictionary to hold the month details we want to display:
- Now switch to the implementation file and add the @synthesize commands to the top.
- In vewDidLoad, setup the dictionary that holds the month details:
monthDetails = [[NSDictionary alloc] initWithObjectsAndKeys:@”31″, @”January”, @”28 (29 in a leap year)”, @”February”, @”31″, @”March”, @”30″, @”April”, @”31″, @”May”, @”30″, @”June”, @”31″, @”July”, @”31″, @”August”, @”30″, @”September”, @”31″, @”October”, @”30″, @”November”, @”31″, @”December”, nil];
- Remember to release this dictionary in viewDidUnload and the properties in dealloc if you’re not using ARC in your project.
- If it’s not already present, add the - (void) viewWillAppear:(BOOL)animated method as below:
- In viewWillAppear, we set the month name label to display the selected month string which we’ll be passing from the root view controller and then set the number of days label to display the appropriate day string from the dictionary.
- That’s almost it for the details view controller, all that’s left to do is switch back to the XIB file and set the outlets for our two labels to the appropriate properties.
- Once done with that, switch to the root view controller implementation file and it’s time to add the detail view into the navigation controller.
- First we need to import the detail view controller’s header file, so do this at the top above the @interface rootViewController () command and beneath the import for the rootViewController.h file.
- Now find the - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath method and take a look at the comments:
- If we need to do anything for a specific cell, we do that.
- We initialise a new detail view controller.
- We pass the selected item to the detail view controller.
- We push the detail view controller onto the navigation controller stack.
And that should be it, so give your app a twirl. If you don’t want to use the same detail view controller for each cell, then all you do is set up a check for the indexPath.row (either in an if.. else or switch statement and pass the appropriate view controller using the same steps as above, here’s a sample from the settings view controller of FootPath: