iOS 7 : Disable UINavigationBar Translucency For Entire App

26,357

Solution 1

if you set the translucence of the first navigation bar in the stack to false [self.navigationController.navigationBar setTranslucent:NO], it will reflect in all the following NavigationViewController that are pushed to that stack.

Solution 2

Here is a Swift solution if you want to apply this Styling to the whole app.

in the AppDelegate class add this to the didFinishLaunchingWithOptions:

For Swift 2:

UINavigationBar.appearance().translucent = false

For Swift 3+:

UINavigationBar.appearance().isTranslucent = false

Solution 3

It seems very simple with this code in appDelegate didFinishLaunchingWithOptions (works fine with iOS 8 and above versions)

[[UINavigationBar appearance] setTranslucent:NO];

Solution 4

Adding this in case anyones still battling this.

You can fool it though by specifying a non exist image, which will make the nav bar INCLUDING it's tool bar go opaque

[[UIToolbar appearance] setBackgroundColor:[UIColor colorWithRed:219.0/255.0 green:67.0/255.0 blue:67.0/255.0 alpha:1.0]];

[[UIToolbar appearance] setBackgroundImage:[[UIImage alloc] init] forToolbarPosition:UIBarPositionAny barMetrics:UIBarMetricsDefault];

Solution 5

I think you are right about no appearance proxy being available for this property. Are you using UINavigationControllers or UINavigationBar objects? If you are using UINavigationBars you could subclass it and create a non-translucent nav bar.

Header file:

#import <UIKit/UIKit.h>

@interface ABCNonTranslucentNavBar : UINavigationBar

@end

Implementation file:

#import "ABCNonTranslucentNavBar.h"

@implementation ABCNonTranslucentNavBar

- (void)drawRect:(CGRect)rect
{
  [self setTranslucent:NO];
}

Then just replace the UINavigationBars with your subclass. You could also do something similar with a subclassed UINavigationController.

Share:
26,357
MikeS
Author by

MikeS

#SOreadytohelp

Updated on July 09, 2022

Comments

  • MikeS
    MikeS almost 2 years

    Is there a way to disable UINavigationBar Translucency for an entire application?

    I'm aware that using [self.navigationController.navigationBar setTranslucent:NO] can fix this issue for a single controller, but I have a lot of UINavigationBars in my application and this is a pretty tedious solution.

    I've tried [[UINavigationBar appearance] setTranslucent:NO], but that functionality is surprisingly not supported. Doing that results in Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** Illegal property type, c for appearance setter, _installAppearanceSwizzlesForSetter:'

    If I HAVE to, I can go through my entire app setting UINavigationBars to disable translucency one by one, but there must be some more elegant solution to this issue...

  • MikeS
    MikeS over 10 years
    That is definitely an interesting idea, but a bit of a pain. Maybe there is an easier way...? Regardless of the answer to this question as of right now, I would be shocked if iOS 7.1 doesn't add a translucency appearance proxy. Also, to answer your question, I am using UINavigationControllers, not just the bar.
  • huggie
    huggie over 10 years
    How about using method swizzle and just patch it on viewDidLoad?
  • Sam Grossberg
    Sam Grossberg over 10 years
    You can also subclass UINavigationController and override the designated initializer to set self.navigationBar.translucent = NO
  • Christian Schnorr
    Christian Schnorr over 10 years
    Doing this is -drawRect:... Have fun watching your app break ;)
  • Sjoerd Perfors
    Sjoerd Perfors about 10 years
    when applying this to the uinavigationbar you will end up with a black statusbar :(
  • Roshan
    Roshan about 10 years
    If you are using the storyboard, deselect transparency from UINavigationController.
  • Andy Riordan
    Andy Riordan over 9 years
    Note that this is dangerous, as it will not call the original UINavigationBar implementation of willMoveToWindow:. The category method replaces the original implementation of the method entirely, so you're actually skipping the original UINavigationBar implementation and calling UIView's implementation directly. stackoverflow.com/questions/6168058/…
  • Daniel Rinser
    Daniel Rinser over 9 years
    It will only set it to translucent for this one navigation stack. If you have any modal navigation controllers, multiple tabs or any other kind of more complex navigation patterns, it won't work.
  • kshitij godara
    kshitij godara over 9 years
    so you have to set each and every stack by like this
  • Daniel Rinser
    Daniel Rinser over 9 years
    Yes, sure. But the point of this question was if there is a way to set it globally (like via UIAppearance), and that's exactly not what you're doing. Moreover, you're saying in your answer that it "will be set for the whole app", which is not true.
  • atreat
    atreat about 9 years
    This solution is not complete if you display any modal view controllers or anything that does not occur within the navigation controller.
  • atreat
    atreat about 9 years
    Its a terrible idea to override methods using categories. In fact, in iOS 8.3 it seems the category methods which override class methods will not be called.
  • Septronic
    Septronic over 8 years
    I'm not sure why someone gave this a negative score, I used this and worked perfectly! I've voted it up!
  • Septronic
    Septronic over 8 years
    Definitely maybe! Thanks anyway.