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
Print
Listen
By
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!
Brian, You would need to create a view with places to put the data (e.g. a "contact" view), and in the method where you are pushing the view on the stack, you would set a property in the view controller for the "contact" view with a pointer to an object that is holding that data. Then in the viewWillAppear method in the "contact" view, you would set the values of your labels or text fields for the view with the appropriate data. Hope that makes sense! Will be a good topic for a follow up screencast when I have more time :-)
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.
Very good tutorial on combining these controllers - Navigation and Tab Bar. Most iPhone development books that I've read so far handle them independently and then you're left with figuring how to incorporate both within the same app. Great job!!
Where was the vidcast on Google that explains how to set up different views for each cell/book when you click on the button?
Hi elizabeth yes must agree with everyone people like you don't know just how help you are. I spent ages creating a tabbarcontroller that has navigation controllers and table views using ib it took me a long while your explainations here actually clear up a lot of my misconceptions with how I did it. My biggest problem was with setting button on the navbar that can react with my code via the delegate but I think what you have said might cure it can't wait to try have you done any other vid cast? Be interested to view x
With help such as this tutorial, I successfully completed my first 3 apps, and am working on more. Thanks again to Beth for posting this.
In reviewing it, I am confused about your sizing of the view window when using the status bar, nav bar, and tab bar. As I understand it, these are 20, 44, and 49 pixels high, a total of 113 pixels of 480. That leaves 367 pixels, yet in the video you say to size the view as 346 pixels high. Why is that?
Beth, thanks a bunch for these Tutorials. They did help me kickstart my iphone knowledge. What an unfriendly developer environment! No wonder why the iphone is not getting any major corporate adoption. But my son loves it for video games !
Also wanted to mention that you have a beautiful voice. You should really come with more tutorials like these ones.
Thanks Elizabeth for the tutorial(s). Thanks to share your work. I can use now IB for this, very helpful.
I tried to add a "search display controller & search bar" following the TableSearch example from apple. But the structure is quite different. Can you give me a way to implement a search function ?
Hi Elizabeth,
Thanks for lovely explanation . I have a question " None of my pictures " Default.png" or two other images for button are getting displayed . Instead i am seeing just
black shadow . Please help .
Thanks
Vivek,
Thanks for your comment. Are you using single layer PNG files? Double check the file type.
Elisabeth
Thanks all for your comments, I'm slowly attempting to catch up and respond to you.
Nice tutorial. I need some help accessing navigation bar in this model. How do I change the color or title of navigation bar here ?
Hi Tebe,
Check out the reference on UINavigationController. You may need to assign a delegate (UINavigationControllerDelegate protocol) too.
Here's some good info on how to modify the navigation bar:
http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UINavigationController_Class/Reference/Reference.html
Elisabeth
Oh, and specifically for the title , you should be able to do self.title = @"..." in the viewDidLoad method in the Navigation Controller.
Elisabeth,
This is hands down the best iPhone tutorial on the web. You are really good at this and should consider doing an in depth series. I know books are your thing with O'Reilly, but honestly, books and newspapers are becoming a thing of the past. You have the chops to cross over so get your publisher to foot the bill and get cranking. I think you'll find there is a big market for it. Anyway, thanks so much, I learned alot!
Michael,
Thanks for your comment! I'm glad you found it helpful.
I actually *am* doing video :-) I just published a video course on iPhone web apps:
http://oreilly.com/catalog/0636920001515
I would like to do more videos on native app development, just need to find the time.
Cheers,
Elisabeth
As a matter of fact I found that link on my own shortly after I left you the message (thanks for the quick reply, just saw it today). I then promptly signed up for Safari Books online and had viewed the first 3 sections by 6AM the next morning! I had to work or I would have joined you online for the last installment. It seemed like forever before they posted it this past monday. In the meantime I got to compare your work to that of your peers on Safari Online (you're still the best :) ).
One of the viewers asked a question about the video link in the player app (it didn't make sense to you the way he had phrased it) and I think he was looking for a way to link to video stored on the phone as apposed to the website (faster load, less chance of breaking). The thought had crossed my mind as well.
I was wondering how I might do that. Is it possible to create a video resource like an icon in the resources folder? Perhaps, if I kept the vids separated amongst the other iTunes media and linked to them there, I could then make the content an add-on sale... How would these options change your url code?
MP
PS Please Go Native ASAP!