Saturday, September 10, 2011

How to load a custom RootViewController in a NavigationController via XIB

This is basically an addendum to my previous post Add a UINavigatorController UI and load from XIB in an empty (single window) iOS App;

Once you have a base or customized UINavigationController loaded via XIB, you might want to load a custom UIViewController into that Navigation Controller. This is actually very simple.

First write a custom UIViewController via the normal Objective-C derivation process. I am not going into that detail. Let's say, you call it, RootViewController

Now, you just need to select the View Controller object in the tree under Navigation Controller. See below:

Now, in the Identity inspector, set the class to RootViewController. See below.
That's it. Now if you build and run, iOS automatically creates an instance of your customized RootViewController class and load it up in the Navigation Controller.

It's that simple.

Add a UINavigatorController UI and load from XIB in an empty (single window) iOS App.

There are a zillion tutorials out there that do this. However, some of them got outdated a bit due to iOS 5 changes and some of them do not really focus on UINavigationController. So this is my attempt to go through the motions:

The goal:

Create an empty (single window app) and load up a customized UINavigationController class via a XIB.


Many times, you want to customize the crap out of UINavigationController and somehow Apple does not give enough flexibility in the API.  For example, you cannot create a customized UINavigationBar in a customized UINavigationController via the API.

However, if you load up the customized UINavigationController (let's call it MyNavigationController) from XIB, you could attach a customized UINavigationBar to your NavigationController.

Weird? May be, I don't know enough to say yes or no.

Let's just get on with it.

Step 1: Create a brand new project with an empty app. Call it "TestApp".

2. Build and run the app, if you want. You will see a single window app with nothing in it.

3. From file menu, choose "New File" and create UIViewController subclass. Name the class MyNavigationController and base class "UINavigationController". Check the 'With XIB ..' option. This will create 3 new files for you. MyNavigationController.[m,h,xib].

4. Edit and fix the XIB. Remove the "View" from it and add a "Navigation Controller" object from the library.

Before you fix, it looks like this:

After you fix it, it should look like this:

5. Go ahead and add anything else you want in this view. For example, my view looks like this:

6.  Update the Class name for File's owner to MyNavigationController:

7. Update the Nib name and class name for Navigation Controller object.

8.  Add the following to your AppDelegate.h file into appropriate lines (I am assuming you know where).

#import "MyNavigationController.h"

@property (strong, nonatomic) ViewController *viewController;

9. Add the following to AppDelegate.m, didFinishLaunchingWithOptions function (an empty function should already be there)

self.viewController = [[[NSBundle mainBundle] loadNibNamed:@"ChannelNavigatorViewController" owner:self options:nil] objectAtIndex:0];
[self.window addSubview:viewController.view];

After you add the above lines, the function would look like this:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    // Override point for customization after application launch.
    self.window.backgroundColor = [UIColor whiteColor];
    self.viewController = [[[NSBundle mainBundle] loadNibNamed:@"MyNavigationController" owner:self options:nil] objectAtIndex:0];
    [self.window addSubview:viewController.view];
    [self.window makeKeyAndVisible];
    return YES;

10. Now you are almost done. Build and run. You should have an app that loads your XIB and your custom MyNavigationController object.

11. Let's customize your NavigationController a bit. For fun, lets change the Navigation Bar color to red. After all, this was the whole point of this whole exercise.

In your MyNavigationController.m file, function viewDidLoad, add the following lines to change the Navigation Bar color.

self.navigationBar.tintColor = [UIColor redColor];

After you add, the function should look like this:

- (void)viewDidLoad
    [super viewDidLoad];
    self.navigationBar.tintColor = [UIColor redColor];

If you compile and run, you will see a customized Navigation Bar.

12. Well, really, the fun just started. After this step, you can create a custom UINavigatorBar and attach it to your MyNavigatorController. However, I will document that part another day.