views:

643

answers:

2

There is a custom UIImageView under "Black Translucent" UINavigationBar, but I'm not too happy with the result. The custom image is not visible enough and while changing navigation bar alpha value brings it more visible, it makes the navigation bar title and buttons less visible.

Question: I want a fully visible custom UINavigationBar background image with fully visible bar title and buttons. Any ideas how would I get all of that?

A: 

may be this can help

www.gauravv.com/2009/12/29/iphone-development-tip-custom-uinavigationbar/

Gaurav Verma
Nice, perfect for background! However my image is so light I really want to change the text color, too. 100% correct answer to the question, I just need to be more detailed with my questions in future :)
JOM
+2  A: 

I wanted a custom UINavigationBar background image too, and ended up solving it by:

  • In the UINavigationController's initialisation, I created a CALayer that had contents set to the background image, and the frame set accordingly.
  • I added that layer to the UINavigationBar's layer (at index 0, in the background): [self.navigationBar.layer insertSublayer:imageLayer atIndex:0]

At this point, it looks okay at first, but if you do any navigation, labels and buttons disappear behind the 'background' layer. So,

  • I created a subclass of CALayer that changed the behaviour of insertSublayer:atIndex: so that no layers are inserted beneath the background layer.

Like this:

 @implementation CTNavigationBarLayer 
 - (void)insertSublayer:(CALayer *)layer atIndex:(unsigned)idx {
     if ( idx == 0 ) idx = 1;
     [super insertSublayer:layer atIndex:idx];
 }
 - (void)addBackgroundLayer:(CALayer*)layer {
     [super insertSublayer:layer atIndex:0];
 }
 @end
  • Using a category on UINavigationBar, I overloaded the +layerClass method to return [CTNavigationBar class], so the navigation bar uses the custom layer.

Of course, this changes the behaviour of all UINavigationBars in your app, so if this isn't what you want, you'd want to seek an alternate way. You could subclass UINavigationBar, but then the only way to get that subclass to be used in a UINavigationController is via IB (or do some rather interesting mucking about to do it programmatically)

  • Finally, back in the UINavigationController initialisation, I replaced the layer insertion with a call to the addBackgroundLayer: method I wrote.
Michael Tyson