Brian
Brian

Reputation: 31302

How to change the color of navigation bar on a specific view

I need to change the color of my navigation bar on only some specific views. There are many discussions about modifying the color of navigation bar, like https://stackoverflow.com/a/18870519/938380, but they all change the color of navigation bar on every views under the same navigation hierarchy.

I want to change the color on specific views and keep other views the same color. How do I achieve this?

Upvotes: 3

Views: 3548

Answers (4)

ricks
ricks

Reputation: 3324

For Swift 4 use

override func willMove(toParentViewController parent: UIViewController?) {
    self.navigationController?.navigationBar.barTintColor = .red
}

It gives a cleaner animation

Upvotes: 7

Rory McKinnel
Rory McKinnel

Reputation: 8014

I handle this kind of thing through an extension to UIViewController. In my case I want to make selected navigation bars transparent. You could extend this to deal with colors. This saves pasting the same code in multiple controllers. Code below.

From viewWillAppear you call [self makeNavigationBarTransparent]. From viewWillDisappear you call [self restoreNavigationBar]

For your case you would simply extend this to add makeNavigationBarColored.

An option is to also sub class UINavigationController to create a class which has a particular color. In its implementation use this extension to set the color. In your storyboard make any controllers you want this color be of your new class type. Then you are doing all this from storyboard.

UIViewController+TransparentNavigationBar.h

#import <UIKit/UIKit.h>

@interface UIViewController (TransparentNavigationBar)

/** Makes the current navigation bar transparent and returns a context holding
 * the original settings.
 */
- (void) makeNavigationBarTransparent;

/**
 * Restores the current navigation bar to its original settings.
 */
- (void) restoreNavigationBar;

@end

UIViewController+TransparentNavigationController.m

#import "UIViewController+TransparentNavigationBar.h"
#import <objc/runtime.h>

@interface VSSNavigationBarContext:NSObject

/** Backup of nav bar image used to restore on push. */
@property UIImage *originalNavBarBackgroundImage;
/** Backup of nav bar shadow image used to restore on push. */
@property UIImage *originalNavBarShadowImage;
/** Backup of nav bar color used to restore on push. */
@property UIColor *originalNavBarColour;

@end

@implementation VSSNavigationBarContext

- (id) init {
    self=[super init];
    if (self){
        self.originalNavBarBackgroundImage=nil;
        self.originalNavBarShadowImage=nil;
        self.originalNavBarColour=nil;
    }
    return self;
}

@end

static char const * const ObjectTagKey = "NavBarContextTag";

@implementation UIViewController (TransparentNavigationBar)

- (VSSNavigationBarContext *) getContext
{
    VSSNavigationBarContext *context=(VSSNavigationBarContext *)objc_getAssociatedObject(self, &ObjectTagKey);
    return context;
}

- (void) makeNavigationBarTransparent{
    VSSNavigationBarContext *context=(VSSNavigationBarContext *)objc_getAssociatedObject(self, &ObjectTagKey);
    if (context == nil){
        context=[[VSSNavigationBarContext alloc] init];

        context.originalNavBarBackgroundImage=[self.navigationController.navigationBar backgroundImageForBarMetrics:UIBarMetricsDefault];
        context.originalNavBarShadowImage=self.navigationController.navigationBar.shadowImage;
        context.originalNavBarColour=self.navigationController.view.backgroundColor;

        // Store the original settings
        objc_setAssociatedObject(self, &ObjectTagKey, context, OBJC_ASSOCIATION_RETAIN);
    }

    //
    // Make transparent
    //
    [self.navigationController.navigationBar setBackgroundImage:[UIImage new]
                                                  forBarMetrics:UIBarMetricsDefault];
    self.navigationController.navigationBar.shadowImage = [UIImage new];
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0f){
        self.navigationController.navigationBar.translucent = YES;
    }
    else{
        self.navigationController.navigationBar.translucent = NO;
    }
    self.navigationController.view.backgroundColor = [UIColor clearColor];
}

- (void) restoreNavigationBar
{
    VSSNavigationBarContext *context=(VSSNavigationBarContext *)objc_getAssociatedObject(self, &ObjectTagKey);
    if (context != nil){
        // Restore original
        [self.navigationController.navigationBar setBackgroundImage:context.originalNavBarBackgroundImage forBarMetrics:UIBarMetricsDefault];
        self.navigationController.navigationBar.shadowImage = context.originalNavBarShadowImage;
        if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0f){
            self.navigationController.navigationBar.translucent = YES;
        }
        else{
            self.navigationController.navigationBar.translucent = NO;
        }
        self.navigationController.view.backgroundColor = context.originalNavBarColour;
    }
}

@end

Upvotes: 0

alex_izh
alex_izh

Reputation: 527

if you use standart navigation bar, you can't do it. But you can use some cheat ;) For example, you can add this code(or something like this) to your controller:

 - (void)viewDidAppear:(BOOL)animated {
     [super viewDidAppear:animated];
     oldColor = self.navigationController.navigationBar.backgroundColor;//probably barTintColor instead of backgroundColor
     self.navigationController.navigationBar.backgroundColor = [UIColor yellowColor];
 }
 - (void)viewWillDisappear:(BOOL)animated {
     [super viewWillDisappear:animated];
     self.navigationController.navigationBar.backgroundColor = oldColor;
 }

Upvotes: 2

user3468361
user3468361

Reputation: 7

You Can Set Bar Tint Property OF navigationController

I hope this one help you

[self.navigationController.navigationBar setBarTintColor:[UIColor redColor]];

Upvotes: 0

Related Questions