Custom UINavigationBar with iOS 5

October 18th, 2011

What’s new for iOS 5?

Well for one, a major upgrade to the UIKit contained in the seemingly simple UIAppearance protocol.

With the UIAppearance protocol, you can modify the appearance of all instances of a particular object. This is very powerful, but what it did was break a lot of old code.

Before the UIAppearance protocol, Developers had to do many strange things in order to get a custom look to their UINavigationBar or UITabBar. Up to, and including overriding the -(void)drawRect: method of the objects themselves.

For example, you could customize the UINavigationBar prior to iOS 5 as follows:

@implementation UINavigationBar (CUSTOM_DRAW)

- (void)drawRect:(CGRect)rect {
UIImage *img = [UIImage imageNamed:[NSString stringWithFormat:@"%@_%@",@"navbar", ((UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation) && (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)) ? @"l" : @"p")]];
[img drawInRect:CGRectMake(0, 0, self.fsw, self.fsh)];


Ugh… what a lot of code. Just to handle different orientations and devices.

Now, however, the same can be done with just a few lines of code:

[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"navbar_p"] forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"navbar_l"] forBarMetrics:UIBarMetricsLandscapePhone];

And Voila! Now you have a custom appearance UINavigationBar.

BUT… what happens if you don’t upgrade to iOS 5? Anyone running iOS 5 with an old iOS 4.x app is going to be very disappointed. Most of the old methods of getting custom appearances are completely overridden by the new UIAppearance Protocol. Even overriding the -(void)drawRect: method I put above is ignored in favor of the new stuff. So that nice custom-looking Navigation Bar or Tab Bar? Gone. You get bland old iPhone blue… which is going to make your otherwise very pretty app – very ugly.

So, make sure your apps are running under iOS 5 – not just in function, but also in appearance.

Stephen Furlani

Stephen has worked as a Biomedical Software Engineer on real-time and medical imaging applications on both Windows and Mac OS platforms respectively. As a Mobile Developer he leverages that experience on current projects.

6 Responses to “Custom UINavigationBar with iOS 5”

  1. Brian says:

    I created a new iOS5 project in Xcode 4.2 Build 4D199 and tried to set the appearance of the UINavigationBar as described above, but nothing happens.

    The only way I can get it to work is to set the appearance on the instance of the UINavigationBar.

    Like…[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"navbar-iphone.png"] forBarMetrics:UIBarMetricsDefault];

    Any ideas on what is going on?

  2. Stephen Furlani says:

    Where are you trying to set the appearance?
    The code I posted above is in the ‘-(void)viewWillAppear:’ method of the viewController.

  3. Andrew says:

    Do you have a solution for iOS 5 using MFMailComposeViewController? I can no longer get the default title “new message” on the nav bar to go away. My custom background image shows, but I have a logo in the center and “new message” is displaying over top of it. I’ve tried setting the title, but it seems to be ignored. I know the docs say not to modify email composition interface, but I was approved on iOS 4 with it and tons of apps do it. Just need the iOS 5 way.

  4. Tod Cunningham says:

    Using [UINavigationBar appearance] will work when setup in the AppDelegate. As using the appearance method will adjust future instances of the nav bar.

  5. Simon says:

    Can you resize the navbar with [UINavigationBar appearance]?

  6. Stephen Furlani says:

    @Simon, No, you can’t resize the navbar.
    @Andrew, Unfortunately, I don’t think so.

Leave a Reply