views:

713

answers:

2

The design I've been given for an iPhone app I'm working on calls for a 1px red line at the bottom of the navigation bar. I know how to draw a line with Quartz and -drawRect, but how do I get access to the UINavigationBar's view? Or would it work to draw the line in the app's main view, on top of everything else?

Duncan Wilcox's answer below works to get the line drawn, but then buttons on the bar become impossible to press.

If I do [self.navigationItem.titleView.superview sendSubviewToBack:titleView] then buttons that are created in nib files work, but not ones that are dynamically added.

+1  A: 

I guess the answer depends on where you want the red line, as part of the navigation bar or just under it. That would be only 1 pixel difference, but designers are demanding these days :)

If you want it below the navigation bar you definitely have to put it in all of the app's views where the line is needed.

There's a surprisingly simple way to alter the look of the navigation bar, I used it for skinning the entire navbar look but it will probably work for even only some parts of the navbar if you make the image partially transparent.

Basically we want to skin the UINavigationItem of a UIViewController that's in your navigation hierarchy.

  • create a 320x44 image containing your custom navbar look
  • add a UIImageView to the XIB where the UINavigationItem is
  • link the titleView property of the UINavigationItem to the UIImageView

This almost works, except that the title view will be resized in wierd ways. To fix that I have a UIImageView subclass that keeps the image properly set:

@implementation TitleViewHack
- (void)setFrame:(CGRect)frame
{
    frame.size.width = 320;
    if(frame.origin.x > 0 && frame.origin.x < 20)
     frame.origin.x = 0;
    [super setFrame:frame];
}
@end

So instead of using a UIImageView above you'll use this TitleViewHack class.

duncanwilcox
haha, that's a clever hack! did you run into any issues with the titleView interfering with buttons on the navigation bar, or is it automatically placed behind them?
lawrence
I actually only use it on the home screen of an app, and there aren't any buttons there. I guess there might be issues with standard navigation buttons. In that case you could try the technique of setting the background color and using the colorWithPatternImage thing.
duncanwilcox
It turns out that it does interfere with buttons. I ended up overriding [UINavigationBar drawRect] and placing the image there with [UIImage drawInRect:].
lawrence
A: 

This is what I've settled upon:

// UINavigationBar subclass
- (void)drawRect:(CGRect)rect {
    UIImage *image = [UIImage imageNamed: @"background_navbar.png"];
    [image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
lawrence
Note that imageNamed is considered troublesome http://www.alexcurylo.com/blog/2009/01/13/imagenamed-is-evil/
duncanwilcox