noizZze

iPhone: Black Navigation Bar in "More..." View

On iPhone, there’s the tab bar control that we, developers, can use to switch between several pages. It appears as a black stripe with icons at the bottom of the screen. Probably, the most famous is the tab bar of the Clock application:

Clock tab bar

It can show up to 5 icons and if there’s not enough space left, the last one is replaced with the “More …” item. When clicked, it shows the nice view with the list of all available options that didn’t fit into the tab bar. UITabBarController delegates the job to the UINavigationController. Now why I tell all this?

By default, the UINavigationController uses that standard blue top bar, but what if I want it to be Black as in the rest of my app?

First, let’s change the style of the “More …” page top bar. It’s all pretty straight forward as you can see. Just get the navigation controller and set the style of its bar:

1
tabBarController.moreNavigationController.navigationBar.barStyle = UIBarStyleBlack;

Finally, let’s change the style of the bar on the “More …” / Edit page (that says “Configure” by the way). It appears that you can’t drill down into the object model like above, but have to catch the moment when the editor is about to come out and do the magic. For this to happen, you needthe tab bar delegate (UITabBarControllerDelegate protocol) and use the tabBarController:willBeginCustomizingViewControllers: callback to nail it:

1
tabBarController.delegate = self;

and later:

1
2
3
4
5
6
- (void)tabBarController:(UITabBarController *)tabBarController
        willBeginCustomizingViewControllers:(NSArray *)viewControllers {
    UIView *views = [tabBarController.view.subviews objectAtIndex:1];
    UINavigationBar *navBar = [[views subviews] objectAtIndex:0];
    navBar.barStyle = UIBarStyleBlack;
}

In the above 3-liner, you can see that we do the trick to actually find the navigation bar. It works nicely on iPhone 3.0, but may change in the future, so be careful.

Don’t forget that you can always subclass UITabBarController and hide all this customization logic inside to stay on the clean design side. In my work, I do that and used the tabBarController here to clearly state what model we operate on.

That’s all, folks. Hope it helped someone to save a couple of hours.