`

[iOS开发教程-4]Create a UITabBarController from scratch

    博客分类:
  • iOS
 
阅读更多

http://www.iphonedevcentral.com/create-uitabbarcontroller/

 

Create a UITabBarController from scratch

Tab bar based apps are probably as common as table-based apps and it’s even more common to see them combined. That’s what we’re going to do in this tutorial.

There is a very easy way of creating a tab bar application. In fact, it’s so easy it requires no work whatsoever. When you choose to create a new iPhone application in Xcode, one of the options is  Tab Bar Application.   Just the bare-bones template provided by Apple gives you a fully-functioning app with two tabs. That is not what this tutorial will be about. We are going to create a tab bar controller programatically. It’s really a lot easier than most people think.

Prerequisites

This tutorial is a continuation of my  previous tutorials   so if you haven’t followed them, it’s a good time to catch up.

We’re going to be starting off from a slightly modified version of the previous source code. You can download the primer code for this tutorial here:MyDVDLibrary04Primer . The only changes made were some name changes (DetailViewController   became  DvdInfoViewController ) and I organized all classes into groups.

Also, I’ve recently upgraded to OS X Snow Leopard + Xcode 3.2 with iPhone SDK 3.0 (not 3.1 yet) so the project was compiled on that platform.

 

1. Create DetailViewTabBarController class

We’re going to add a view controller that will create a tab bar controller with three tabs: Info, Stats and Borrowers. Each of the tabs will be a separate, self-contained view controller. We already created one of them,  DvdInfoViewController , which was previously called  DetailViewController . The reason I renamed it is that the real detail view controller will now be our tab bar controller.

In Xcode, right-click on the  View Controllers   folder from the the  Groups & Files   panel on the left and choose  Add -> New File . Choose  UIViewController subclass   from the  Cocoa Touch Class section  and click  Next . Name the file  DetailViewTabBarController .

Note: You may be wondering why we didn’t choose a UITabBarController subclass instead. As you can see that option wasn’t even offered. This is because UITabBarController is not meant to be subclassed. Instead, we create a generic view controller to which a tab bar controller will be assigned.

2. Create DvdStatsViewController and DvdBorrowersViewController

These are the new view controllers I mentioned previously. We already have our  DvdInfoViewController   that will be in the first tab, so let’s create the remaining two.

In Xcode, right-click on the View Controllers   folder and choose Add -> New File . Choose UIViewController subclass   and name the file DvdStatsViewController .

To create  DvdBorrowersViewController   do the same thing, only name it  DvdBorrowersViewController .

That’s it about those two controllers for now. I’m not going to cover actually filling them with any content since that’s not the point of this tutorial. We will leave them here as placeholders for future tutorials when we cover Core Data and RSS feed processing.

3. Set up DetailViewTabBarController

Since we’re going to be coming to the tab bar controller from the  RootViewController , we need to pass it DVD info from the row that was tapped. We can do that in a custom init method in  DetailViewTabBarController . You’ll see how it’s used later when we instantiate it in  didSelectRowAtIndexPath   method ofRootViewController .

We’re also going to need a handle on the data about the DVD that was tapped on the front page.

Declare it all in  DetailViewTabBarController.h

@interface DetailViewTabBarController : UIViewController {
    NSDictionary *dvdData;
}
-(id)initWithDvdData:(NSDictionary *)data;
@end
Next, let’s define  initWithDvdData   in  DetailViewTabBarController.m
-(id)initWithDvdData:(NSDictionary *)data {
    if (self = [super init]) {
        dvdData = data;
    }
    return self;
}

All we’re doing here is setting local instance variable  dvdData   to whatever is passed in. We now have a handle on the DVD data and can use it across all the view controllers.

4. Implement loadView method in DetailViewTabBarController

loadView   is a method on UIViewController that can be overridden in case you want to build your view from ground up. That’s exactly what we want to do so let’s override  loadView   now. Let’s discuss it piece by piece;

- (void)loadView {
    UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
	contentView.backgroundColor = [UIColor whiteColor];
	self.view = contentView;
	[contentView release];

Borrowing the biblical line; in the beginning there was nothing, we need a base view to build upon. So we created an empty view with a white background that takes up the whole screen. We will attach all the other views to it.

Now we need to instantiate all three of our controllers. Each one will become one tab in the tab view.

    // Declare all three view controllers
    DvdInfoViewController *dvdInfoController = [[DvdInfoViewController alloc]
                                                initWithDvdData:dvdData
                                                nibName:@"DetailViewController" bundle:[NSBundle mainBundle]];
    DvdStatsViewController *dvdStatsViewController = [[DvdStatsViewController alloc] init];
    DvdBorrowersViewController *dvdBorrowersViewController = [[DvdBorrowersViewController alloc] init];
 
    // Set a title for each view controller. These will also be names of each tab
    dvdInfoController.title = @"Info";
    dvdStatsViewController.title = @"Stats";
    dvdBorrowersViewController.title = @"Borrowers";

You see the  dvdInfoController   is initialized the same way we did it before in  RootViewController . We pass it  dvdData   that we get from our custom initialization method.

Now the meat of this method, let’s create the actual tab bar controller and give it the three view controllers. You can note that we’re setting the bounding frame to be 320 pixels wide and 460 pixels high. We shave off 20 pixels because the title bar is already taking up, well, 20 pixels.

UITabBarController creates tabs when you call setViewControllers on it and pass it an array with your controllers in it. That’s what’s happening here.

    // Create an empty tab controller and set it to fill the screen minus the top title bar
    UITabBarController *tabBarController = [[UITabBarController alloc] init];
	tabBarController.view.frame = CGRectMake(0, 0, 320, 460);
 
    // Set each tab to show an appropriate view controller
    [tabBarController setViewControllers:
     [NSArray arrayWithObjects:dvdInfoController, dvdStatsViewController, dvdBorrowersViewController, nil]];
And finally, let’s clean up objects we no longer need from memory and add the tab controller view to our parent view so we can actually see it.
    // Clean up objects we don't need anymore
    [dvdInfoController release];
    [dvdStatsViewController release];
    [dvdBorrowersViewController release];
 
    // Finally, add the tab controller view to the parent view
    [self.view addSubview:tabBarController.view];
}

5. Modify RootViewController’s didSelectRowAtIndexPath method to display DetailViewTabBarController

The last step we need to take is to modify  didSelectRowAtIndexPath   in  RootViewController   to display our newly created tab bar controller instead of theDvdInfoViewController   we showed in the last tutorial.

Open up  RootViewController.m   and modify  didSelectRowAtIndexPath   to look like this:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    DetailViewTabBarController *controller = [[DetailViewTabBarController alloc]
                                              initWithDvdData:[dao libraryItemAtIndex:indexPath.row]];
    controller.title = [[dao libraryItemAtIndex:indexPath.row] valueForKey:@"title"];
    [self.navigationController pushViewController:controller animated:YES];
    [controller release];
}

At this point, you can run your project and tapping on a DVD title should take you to the tab bar controller which has three tabs. The first tab contains the movie info, the remaining two are empty. As I mentioned before, we’ll fill those in in the later tutorials or it can be left as an exercise for the reader.

6. Add icon to tabs

The tabs now only have a textual title. Let’s make it prettier by adding an icon to each of them. I only use one image (included in the project) for demonstration purposes but you can have a different image for each tab. The image should be 32×32 pixels PNG file. You don’t need to to create the pretty, shiny, gray and blue images. Just pass it a normal image and the SDK will do the rest.

Add this in the  loadView   method in  DetailViewTabBarViewController.m   implementation file right after we set the titles of the controllers:

    // Set a title for each view controller. These will also be names of each tab
    dvdInfoController.title = @"Info";
    dvdStatsViewController.title = @"Stats";
    dvdBorrowersViewController.title = @"Borrowers";
 
    dvdInfoController.tabBarItem.image = [UIImage imageNamed:@"dvdicon.png"];
    dvdStatsViewController.tabBarItem.image = [UIImage imageNamed:@"dvdicon.png"];
    dvdBorrowersViewController.tabBarItem.image = [UIImage imageNamed:@"dvdicon.png"];

If everything went well, you should see your app looking like this

tutorial020

Conclusion

While it may seem easier to create everything in the Interface Builder, you can see that in this case creating a tab bar controller was a breeze. Adding new tabs/view controllers to it is as easy as adding an object to an array. I hope this tutorial connecting the dots how to go from a table view to a tab bar view in a navigation-based application.

You can download the complete source code to this tutorial here:  My DVD Library Tutorial 4

      
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics