The Right Way… and The Best Way

The Right Way… and The Best Way

If you’ve ever wanted to put a custom image into the title bar of an iPhone app, no doubt you’ve used – or at least run across – code similar to the following:


UIImage * titleImage = [UIImage imageNamed:@"nav_bar_background.png"];
UIImageView * titleImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 42)];
titleImageView.image = titleImage;
titleImageView.contentMode = UIViewContentModeScaleAspectFit;
titleImageView.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight;
[self.myBar addSubview:titleImageView];
[titleImageView release];

And this is a very workable solution.

It’s just not the BEST solution.

The problem with this approach is that if the navigation controller pushes another UIView on the stack, odds are the UIImageView is going to cover your navigation buttons.  Even if the title background image is sent to the back of the z-order.

Double-plus un-good.

The optimal approach to solving this is to implement a category for the UINavigationBar.

What’s a category?

It’s a handy way to extend the capabilities of a built in class without fully having to subclass the whole darn enchillada.  Technically, categories permit a programmer to add methods to an existing class without the need to recompile that class or even have access to its source code.

Take a look:

// UINavigationBar catergory for painting background image in a way that doesn't hide nav buttons.

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

@end

Include this little nugget in your project, and voila – you have a navigation bar image background that works in any orientation and doesn’t hide navigation buttons.

Enjoy.