Custom background for UINavigationBar

When you’re working on an iphone app, more often than not, you’ll be working with the standard SDK elements and then customize those. For a recent project, I had to work with a navigation controller. And of course, the UINavigationBar needed to be customized with a proper image.

Now I had never done this before, and as usual when I don’t know how to do some task, I look in one of my two books. If the answer isn’t there, then Google comes to the rescue. So to customize the background of a UINavigationBar wouldn’t be too much of a problem I thought. And indeed it wasn’t, but I first implemented a wrong solution:

How to do it incorrectly

In the viewWillAppear:(BOOL)animated method of the ViewController, I wrote this:

[self.navigationController.navigationBar insertSubview:[[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"title_bar.png"]] autorelease] atIndex:0];

Basically, it inserts an image with filename “title_bar.png” as a subView into the UINavigationBar. This works fine. In fact, I couldn’t see anything wrong with it. So I went ahead, and added it elsewhere in the code too.

So if this works, what is wrong with it? The behavior is unpredictable. In my title bar, I set the title of the current view, and I added a button on the right hand side. Sometimes the button wouldn’t render, sometimes the title wouldn’t render. Sometimes the behavior was correct only after I went to another view, and then came back to this one. So to keep it short: it is unpredictable, and you don’t want to do it this way.

How to do it correctly

To make this work, you don’t have to write a lot of code. All you need to do is subclass the UINavigationBar class, and implement the drawRect method yourself. This will override the default behavior with what you implement. So each time drawRect is called, we just make sure the “title_bar.png” image is added:

@implementation UINavigationBar (CustomImage)
- (void)drawRect:(CGRect)rect {
	UIImage *image = [UIImage imageNamed: @"title_bar.png"];
	[image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
@end

The drawRect method is automatically invoked when the UINavigationBar will be rendered. Each time this happens, the image will now be automatically drawn in the title bar. Beware though, this is for all UINavigationBar’s in your project.

3 Comments

  • George Apostu
    November 30, 2011 - 15:01 | Permalink

    Thanks a lot! I tried for days to remove the highlight from the tabs.

  • December 14, 2010 - 13:39 | Permalink

    Glad to be of service :)
    I like to surprise my clients too, so I think he’ll be happy you found a way to do what he wanted

  • December 11, 2010 - 02:16 | Permalink

    Thanks for this helpful tip. I have had my share of the ‘wrong way’ of overriding the standard behaviours; this drawRect wisdom promises to save me some hassle. I just finished telling a client I can’t change the colors or images etc of his UINavigation and UITabBar stuff, and now I can pleasantly surprise him monday.

  • Leave a Reply

    Your email address will not be published. Required fields are marked *

    *

    You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>