How to ovverride UINavigationBar appearance if already customized

6.1k Views Asked by At

In the application delegate within my application I call the following method:

- (void)customizeAppearance 
{
    UIImage *gradientPortrait = [[UIImage imageNamed:@"gradient_portrait"] 
        resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];

    UIImage *gradientLandscape = [[UIImage imageNamed:@"gradient_landscape"] 
        resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];

    [[UINavigationBar appearance] setBackgroundImage:gradientPortrait 
        forBarMetrics:UIBarMetricsDefault];
    [[UINavigationBar appearance] setBackgroundImage:gradientLandscape 
        forBarMetrics:UIBarMetricsLandscapePhone];
}

This code allow to customize all the navigation bars within the application. Each bar becomes green since the image I use is green.

Now my goal is to ovveride the above configuration for a specific navigation bar. In particular, during application lifecycle, I open a modal controller using UIModalPresentationFormSheet presentation style. This controller is presented within a UINavigationController. Since I need also to display the navigation bar attached with that UINavigationController, I would like to know how it is possible to customize that bar, without changing the global configuration I set in the application delegate.

I've tried to set both the tintColor property of the navigation bar (presented modally) to [UIColor blackColor] and the barStyle to UIBarStyleBlack, but they don't work. Only barbutton items are affected.

Thank you in advance.

P.S. I'm using iOS 5

2

There are 2 best solutions below

2
On BEST ANSWER

First of all if you don't mind your image stretched you don't need to use the resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0) method.

UIImage *gradientPortrait = [UIImage imageNamed:@"gradient_portrait"];
UIImage *gradientLandscape = [UIImage imageNamed:@"gradient_landscape"];

UIImage *someOtherImage = [UIImage imageNamed:@"someOtherImageName"];

Then, to achieve what you want:

  1. Make sure you subclass the ViewController on with the custom Navigationbar will appear
  2. Use the following to add the default image to all of your Navigation Bars

    [[UINavigationBar appearance] setBackgroundImage:gradientPortrait forBarMetrics:UIBarMetricsDefault];
    
  3. Use the following to add the specific image to navigationbars wich will appear above the subclassed ViewControllers

    [[UINavigationBar appearanceWhenContainedIn:[YOURSUBCLASS class], nil] setBackgroundImage:someOtherImage forBarMetrics:UIBarMetricsDefault];
    

(you can call these methods from somewhere in your app delegate)

btw, if you just want to change the tint color you could just use the tintColor Property instead of all the images.

for more info check out the appearance sections of: UINavigationBar Class Reference

1
On

Subclass UINavigationBar with your custom class and se different appearance on it. Then use your custom class on that particular place where you what to have different look.