Tab bars and Navigation bars together

By Elisabeth Robson
June 24, 2009 | Comments: 25

The TableView is a common way to display data on an iPhone. For example, news apps like Wall Street Journal, New York Times and Huffington Post all use a table view to display a list of stories. When you click on one of those stories, you see the full news story in a detail view. At the top of these apps, you see a navigation bar that allows you to navigate back to the list of stories, and at the bottom, a tab bar that lets you select among different app functions or topics, for example.

Combining a tab bar with a table view and navigation bar isn't very difficult, but it took me forever to figure out how to do it properly. I found the explanation of how to combine tab bars and navigation bars on Apple's website woefully inadequate. I spent some time studying one of the examples that comes with the Apple documentation for Tab Bar Controllers, called TheElements, which builds this kind of app programmatically. After studying that for a while, it started to make more sense, but I really wanted to figure out how to do it using Interface Builder. I posted a couple of questions to the cocoadev mailing list, and got some really helpful answers and was eventually able to figure it out.

O'Reilly Workshop: Build, Compile, and Run Your iPhone App in 2 Days — Learn to build mobile applications for Apple's iPhone and iPod touch in this dynamic two-day workshop. You'll learn the basics of the Cocoa programming environment, Xcode suite of tools, and the Objective-C language, and then create two iPhone apps. Register today!



I've created an example to demonstrate how to build this kind of app and recorded a screencast partly so I'd never forget again, and also to help anyone else out there who might be struggling with this same challenge. There are lots of little steps that you have to do in just the right order to get it all working. A screencast seemed like the perfect way to demonstrate these steps since a lot of the work happens in Interface Builder and it's much easier to show what actions to take than it is to describe them in text or even with pictures.

If you try to build this app yourself by following the screencast, I'd love to hear how it goes and if the screencast was helpful for you. And if you have any feedback on the process I'm using to build this app, I'd love to hear that too.

Or, to follow along more closely with the code, Click here to view or download the original high resolution .mov file. [254 Mb]

Update: Here's the downloadable code sample

Visit Part II: O'Reilly Books Example updated: Show a different image for each book



You might also be interested in:


25 Comments

Doing the same project in code, no IB, is left as an execise for the reader, right?

I'm not sure why this would be hard, since it's explained quite clearly in the View Controllers document.

http://developer.apple.com/iphone/library/featuredarticles/ViewControllerPGforiPhoneOS/

It's actually easier.
After having your TabBarController, set the required view controller's class to navigation controller, and just drag a generic table view controller directly on the tab bar controller window and you're done.

is the finished code available somewhere?

-bowerbird

Alex: Thanks, I'll give that a try!

Ash: Can you point to the precise page where Apple describes this?

Rudifa: Yes :-) Also, check out TheElements code that you can download from Apple as an example.

Bowerbird: no, but I'll see if I can make that happen

Got a couple of hints from Joe Heck on this app:

I don't need to explicitly identify the datasource and delegate protocols in BooksTableViewController; that comes by subclassing UITableViewController (just a small change, but worth noting).

Also: I don't need the BooksNavController class. I don't actually use it for anything, so I could have created a generic navigation controller without subclassing it, and used the navigationController property in the BooksTableViewController to access it (so I don't need to explicitly create the class and a reference to it in the table view controller). This means I can replace the lines (in BooksTableViewController):

ORBooksAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
[delegate.booksNavController pushViewController:bookDetailViewController animated:YES];

with just:

[self.navigationController pushViewController:bookDetailViewController animated:YES];

A bit simpler and probably better coding style.

Thanks Joe.

AWESOME tutorial! Thank you sooooooo much!

I followed your tutorial and have my app working correctly. My next step however is that I'd like for when the user selects each row they are taken to a separate view. Currently with your tutorial you have all the clickable rows going to the same view.

Do you have a tutorial for this?

Thanks again!!!!

I guess what I mean is I'd like to parse an XML file and the data that's loaded into a view is determined by the row that's clicked. I'm just completely stumped on this...

A huge help in getting started building a UI with IB - thank you!

Great tutorial! Now what if I want to allow the individual rows in the UITableView to be clicked so they are each pushed to a new view (with its own data)?

I realize this is the section of your code to work with (and I believe another controller and its xib must be built per row):
------------------------
NSInteger row = [indexPath row];
if (self.bookDetailViewController == nil) {
BookDetailViewController *aBookDetail = [[BookDetailViewController alloc] initWithNibName:@"BookDetailView" bundle:nil];
self.bookDetailViewController = aBookDetail;
[aBookDetail release];
}
bookDetailViewController.title = [NSString stringWithFormat:@"%@", [booksArray objectAtIndex:row]];

[self.navigationController pushViewController:bookDetailViewController animated:YES];
-----------------------------

How would I go about doing this?

John,
I've posted a new screencast that I hope answers your question.

Elisabeth

Thanks Elisabeth for this great tutorial!

Amazing tutorial thanks so much! I was struggling on exactly this issue and found your vidcast on Google. It was a lifesaver. Thanks much!

Jon,
So glad it was helpful!
Elisabeth

Hi Beth,

Thanks, this was a really useful walk through. Your comments as you coded really solidified my newly learnt thinking about iPhone app development and your tutorial was much more on my level, versus the documentation. Thanks very much !

Ben

Thank you for an amazing tutorial....

Been struggling with that for a while :)

The best voice for an iphone app tutorial i have heard so far also

Good work :)

Love the latest tutorial. Thanks a ton. Now if I wanted to show info. like name, address and phone number on the detail view (instead of an image) how would I go about altering the code to do that?

Cheers!

Thank you so much for this Tutorial. I'm new in iPhone Development and it takes days to trying implementing this. After watching your Tutorial its so easy.

Thanks again.

Elisabeth,

I spent the whole day trying to put a navigation bar inside a tab bar controller. And when I decided to search for help, you appeared on the first page. You saved my day. Everything worked perfectly.

Thanks!

Joao

This definitely save me a great deal of time. I was combining a Tableview with navigation bar with the a Tab bar... your tutorial was great. thanks. Chuck

Thanks for exactly the right approach. It got me past a sticking point.

When I went past this tutorial to push other view controllers onto the nav stack, I got messed up by a typo in Apple's commented code (which leaves out "animated: YES)" at the end of the push code, and leads to a cryptic error. Come on, Apple!

If Elisabeth could lead us through bringing in simple flat database files via SQLite to populate a table view without the elaborate Core Data code, I'd buy all her books!

That's just brilliant, thanks a lot.
It helps a lot to see you in action, and to get the repetitive stuff about releasing the properties or connecting the views in IB

thanks elisabeth! i was trying really hard to combine both tabbar and nav controller before i saw ur page but failed to do so. U reali saved me a lot of time. hugs.

Thanks Elizabeth for this wonderful tutorial. Most of the examples/tutorials on the net, explain each thing separately. I got burned trying to combine them in one app. Here I got exactly what I was looking for.... tabbar with nav bar with table view. Could not have asked for a better simpler tutorial!

I have a another issue now. I am following the same steps you mentioned in my project. I noticed that viewDidAppear in root TableViewController is not getting called when I go to the screen initially, or when returning back to the screen from child screen. I have put in break point and fail to see what I am doing wrong. However, I did notice that if I switch to another tab and then come back, everything works great, including viewDidAppear that gets called.

I did see this behavior in your sample app.

Any ideas???

p.s. This is driving me crazy. ;-


Peter.

Finally, I started retracing all my steps. I found out that my colleague had added a splash controller view to the main window instead of the root controller view. Once I changed this back to add root controller view to the main window, things started working just great.

Everything now works just as expected.

Leave a comment



Popular Topics

Browse Books

News Topics


Got a Question?