Custom UINavigationBar Background

Viewed 52940

I've been trying to set up a custom background for the whole of my NavigationBar (not just the titleView) but have been struggling.

I found this thread

http://discussions.apple.com/thread.jspa?threadID=1649012&tstart=0

But am not sure how to implement the code snippet that is given. Is the code implemented as a new class? Also where do I instatiate the UINavigationController as I have an application built with the NavigationView template so it is not done in my root controller as per the example

15 Answers

You can also override the drawLayer:inContext: method in a UINavigationBar category class. Inside the drawLayer:inContext: method, you can draw the background image you want to use.

- (void) drawLayer:(CALayer *)layer inContext:(CGContextRef)context
{
    if ([self isMemberOfClass:[UINavigationBar class]] == NO) {
        return;
    }

    UIImage *image = (self.frame.size.width > 320) ?
                        [UINavigationBar bgImageLandscape] : [UINavigationBar bgImagePortrait];
    CGContextClip(context);
    CGContextTranslateCTM(context, 0, image.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);
    CGContextDrawImage(context, CGRectMake(0, 0, self.frame.size.width, self.frame.size.height), image.CGImage);
}

And as a complete demo Xcode project on customizing the appearance of UINavigationBar this and this might be helpful.

As Apple itself has said, it is not correct to override methods in Categories. So the best way to customize the background of UINavigarionBar is subclassing and override -(void)drawInRect: method.

@implementation AppNavigationBar
- (void)drawRect:(CGRect)rect
{
    UIImage *patternImage = [UIImage imageNamed:@"image_name.png"];
    [patternImage drawInRect:rect];
}

To use this customized UINavigationBar it should be set as navigationBar property of your UINavigationBarController. As you know this property is readonly. So what should be done is:

- (void)viewDidLoad
{
    [super viewDidLoad];

    AppNavigationBar *nav = [AppNavigationBar new];
    [self setValue:nav forKey:@"navigationBar"];
}

It works for both iOS 5 and 4.3.

Related