There are a wholebunch of tutorials to create a Navigation Controller inside a TabBarController with XCode3. But there are a number of small changes in XCode4 which can trip up someone not familiar with them. So this guide is essentially an updated version of those other guides, designed to create the same simple demo using the new tool.

1. Create a new Project
We are going to start with a Tab Bar Application, so go ahead and create a new project as usual. I'm calling mine Navigation Tab Bar.

2. Select the Tab Bar
Click MainWindow.xib and you should see the integrated Interface Builder. On the left is a section called Objects, select the Tab Bar Controller.

3. Add the Navigation Controller
On the right side of your screen click the Utilities box. This is new in XCode4 and should look familiar if you've been using XCode3. At the bottom find the Navigation Controller and drag it into the Tab Bar in the middle of your screen.

Here you can see I added it as the middle Tab

4. Configure new tab

Back in the Objects section you can now expand the Navigation Controller and select the View Controller object. Now on the right side you can select the Identity Inspector at the top and put in your UIViewController's class name. For the purpose of this demo I am calling it "YourNewViewController" which we will make at the end.

Once that is done switch to the Attribute Inspector and put in the name of your XIB file in the NIB Name section. Note: do not add the .xib extension, this will cause a runtime crash.

5. Create the new UI View Controller

This is probably familiar to you already, create file from the File menu and select a UIViewController subclass.

Be sure to select With XIB for user interface

Use the same file name as you used before.

6. Add an IBAction

We will be adding a button to push a view onto the navigation controller. Open up the header file and add an action.

I just added the buttonPushView line

Switch to the implementation file and add another few lines for a simple call to pushViewController.

This is the simplest pushViewController line I could come up with

7. Add a button

Select YourNewViewController.xib in the file menu. Adding a button is a simple matter of dragging/dropping from the bottom right Objects section.

Next you link the button to the new IBAction by right clicking the button and dragging the arrow to File's Owner, in the Placeholders section. Select buttonPushView.

8. You're done!

All thats left now is the build and run (Command-R). Select the second tab to see your new Navigation Controller and click the button to see it in action.

27
comments:

Thanks so much! I was stuck because I was changing the class of the pre-made view controller to UINavigationController instead of dragging in a new one, which didn't expose the ViewController attribute inside it.

Thank you! I spent hours trying to figure out how to do this using XCode 3 tutorials (some great ones to, but ones that didn't work in XCode 4). I can't believe the solution was a drag-and-drop 10 minute solution. Thanks a ton for sharing this!!

In step 7 instead of adding a button you could add a UITableView. You'll have to setup the tables data source and delegate outlets and your view controller class will need to conform to the UITableViewDelegate and UITableViewDataSource protocols.

I wrote about this last year when I was first figuring it all out, maybe this will help:http://blog.willwinder.com/2010/10/uitableview-which-is-its-own-delegate.html

First: Great Tutorial! :-) Second: (and perhaps a beginner's question) - the view that you're pushing onto the stack when you're clicking the button - that's a non-existant view, right? I mean you're alloc-ing and init-ing it on the fly, which is why its a blank white screen, correct?

My question is this then: what's the syntax for pushing a view that does exist? Like if you want an actual view that you've created and designed (with a .xib file) to be pushed onto the stack - how would you write that?

Cause I created a new UIViewController called "SomeRandomScreen" (giving me the .h , .m , and .xib files.) Then I tried:

I wouldn't call it a "non-existant" view. It is a real view, it just has nothing on it.

When I'm creating a UI programatically, I'll frequently do a simple modification like changing the background to make it easier to see what the heck I'm doing: "targetScreen.view.backgroundColor = [UIColor greenColor];"

That said, the code you posted should work fine. Without seeing the error message when it crashes I can't really say whats wrong with it.

There are a few small steps you can take to figure out what you're doing wrong:

1) Try allocating the empty UIViewController and pushing it onto the navigation controller, but change the background color.

2) Once that works, try pushing the UIViewController I made in the tutorial onto the stack just like you're doing, but with "YourNewViewController". You should be able to push it onto the stack over and over again.

3) Once you get all that working you can try getting your "SomeRandomScreen" loading. Look closely at step 5-7 in the tutorial, since they do exactly what you want to do as far as creating a UIViewController from a NIB.

ok that worked - but here's the REAL question :-)What if I wanted the Navigation Controller that I'm creating to then contain a TableView? But I don't want it be from a UITableViewController, just a regular Table-View?Let me be more specific:1) we have our FirstViewController, SecondViewController and of course the new View-Controller we created as per your instructions called MyNewViewController.2) Because I wanted MyNewViewController to load a view that has a NIB (xib) file, I also created yet another view called "peachScreen", which is a subclass UIViewController, which then gave me a peachScreen.h, peachScreen.m, and peachScreen.xib files (and of course I made the background color of the xib file be peach.)3) Finally, I set this up: MyNewViewController has a button which push-loads the peachScreen view.

All this works just fine.

BUT, if I wanted to now put a table inside of peachScreen - meaning I want to drag a Table-View from the Library/Objects panel (not a Table View Controller! just a Table View) and drop it in the middle of my peachScreen, and resize it so that its like only half the page, and then have the individual cells of that table drill-down and take me to other detail-views - without ever losing my TabBar at the bottom - well how the HECK do I do that? :-)Cause that's what's killing me. This is where I get lost with trying to figure out what controls what. I get crashes and errors - maybe I'm just not connecting things correctly with File's Owner - but I think I'm setting things up right, I'm making sure to include the and - but I'm crashing all over the place.Any tips (or even code) on setting up this "engine" so that it works correctly?

This is great! I have been struggling with this for two weeks! Thank you very much for posting it.

I do have two questions. I am making an app that has 4 tabs, two of which I want to have Navigation Controllers. So I repeated the steps to put a second Nav Controller, having it load a different class and NIB file, but this time I'm getting two errors. A MainWIndow.xib unsupported configuration and an error in my new AboutViewController.m on a line of code I didn't edit; something about UINavigation Controller may not respond to pushViewController animated. but the error shows up in the code below.

I'm trying to make the combined tab and navigation application respond to rotation of the device, but without luck. What I have done is to always return YES in - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientationin all views.

I've been programming for over 20 years but am a total beginner with Xcode.

Perhaps the Xcode 4.2 interface has changed since version 4. The sequence of dialogs in 4.2 looks completely different to the tutorial above. Perhaps my settings are not correct. The create project dialog did not create a mainWindow.xib so I created one myself. I did not see anything called Integrated Interface Builder. I could not arrange a combination of objects to match the Object navigator and the auto generated code in 4.2 is significantly different to the above example.

If found the Introductory tutorials in the Xcode documentation also do not match what I see on the screen. Maybe getting too old for this :-)

Some of my comments in my directions were aimed at people who were upgrading from Xcode3 so that is probably adding some confusion.

I just double checked using version of 4.2 and it looks like things are pretty much the same (I may have been using that version all along). Some of the windows you need to use are collapsed by default but I mention how to open them, most of the code examples I put in my instructions are not auto generated. When I said "Integrated Interface Builder" I meant it is now part of Xcode, it used to be a separate program. Just click on the file ending in .xib and it automatically opens.

Make sure you select "Tab Bar Application" when making your new project, the MainWindow.xib file should definitely be there. The rest of the steps should make more sense after you have that. There are all sorts of config files hidden away to do things like pick which window launches with your program and also some special considerations which you need to do for the "main" window. I think its best (for your sanity at least) to leave the defaults as much as you can until you absolutely need to change it.

Another thing I felt was useful when first starting was to create my UI's programmatically. For me the API's were much more intuitive than the GUI's. Eventually I started to embrace the GUI as a time saver, especially for things like this.

Stick with it, iOS development seems strange for a while but eventually you'll start to see a method to the madness.

Post a Comment

Twitter

Twitter Updates

About Me

Will Winder is a software developer. In his four years of study at UNH he took variety of advanced Computer Science courses including Object Oriented Design, Computer Networks, Artificial Intelligence and Compiler Design. He has been working professionally using C, C++ and Java since graduating in 2006. In his free time he continues to expand his skills by involving himself in many projects, some of which can be seen on this blog.