127

I want the UINavigationBar in my app to be completely transparent and flush with the viewcontroller directly under it. However, the only code I could find makes it translucent but not transparent. I know this can be done in iOS 7 because it is used in the notes app. My question is, what is the code they used to do it?

cory ginsberg
  • 2,898
  • 6
  • 23
  • 37

8 Answers8

296

From this answer

[self.navigationController.navigationBar setBackgroundImage:[UIImage new]
                     forBarMetrics:UIBarMetricsDefault];
self.navigationController.navigationBar.shadowImage = [UIImage new];
self.navigationController.navigationBar.translucent = YES;
self.navigationController.view.backgroundColor = [UIColor clearColor];
self.navigationController.navigationBar.backgroundColor = [UIColor clearColor];

Also, as suggested by Josh in the comments, to put the bar back to default:

[self.navigationController.navigationBar setBackgroundImage:nil
                     forBarMetrics:UIBarMetricsDefault];
Community
  • 1
  • 1
Alan
  • 4,315
  • 3
  • 20
  • 25
79

For Swift3 and Swift4

self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.isTranslucent = true

For Swift2.2

 self.navigationController?.navigationBar.setBackgroundImage(UIImage(), forBarMetrics: .Default)
 self.navigationController?.navigationBar.shadowImage = UIImage()
 self.navigationController?.navigationBar.translucent = true

For Objective-C

[self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
self.navigationController.navigationBar.shadowImage = [UIImage new];
self.navigationController.navigationBar.translucent = YES;
vichhai
  • 2,470
  • 2
  • 14
  • 24
39

Self contained solution as an Objective-C Category:

UINavigationController+TransparentNavigationController.h

@interface UINavigationController (TransparentNavigationController)
- (void)presentTransparentNavigationBar;
- (void)hideTransparentNavigationBar;
@end

UINavigationController+TransparentNavigationController.m

#import "UINavigationController+TransparentNavigationController.h"

@implementation UINavigationController (TransparentNavigationController)

- (void)presentTransparentNavigationBar
{
  [self.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
  [self.navigationBar setTranslucent:YES];
  [self.navigationBar setShadowImage:[UIImage new]];
  [self setNavigationBarHidden:NO animated:YES];
}

- (void)hideTransparentNavigationBar
{
  [self setNavigationBarHidden:YES animated:NO];
  [self.navigationBar setBackgroundImage:[[UINavigationBar appearance] backgroundImageForBarMetrics:UIBarMetricsDefault] forBarMetrics:UIBarMetricsDefault];
  [self.navigationBar setTranslucent:[[UINavigationBar appearance] isTranslucent]];
  [self.navigationBar setShadowImage:[[UINavigationBar appearance] shadowImage]];
}

@end

Now, you can import the category in your UIViewController and call the methods on your navigation controller - for example:

#import "UINavigationController+TransparentNavigationController.h"

- (void)viewWillAppear:(BOOL)animated
{
  [super viewWillAppear:animated];
  [self.navigationController presentTransparentNavigationBar];
}

- (void)viewWillDisappear:(BOOL)animated
{
  [super viewWillDisappear:animated];
  [self.navigationController hideTransparentNavigationBar];
}

And a similar solution in Swift:

import Foundation
import UIKit

extension UINavigationController {

  public func presentTransparentNavigationBar() {
    navigationBar.setBackgroundImage(UIImage(), forBarMetrics:UIBarMetrics.Default)
    navigationBar.translucent = true
    navigationBar.shadowImage = UIImage()
    setNavigationBarHidden(false, animated:true)
  }

  public func hideTransparentNavigationBar() {
    setNavigationBarHidden(true, animated:false)
    navigationBar.setBackgroundImage(UINavigationBar.appearance().backgroundImageForBarMetrics(UIBarMetrics.Default), forBarMetrics:UIBarMetrics.Default)
    navigationBar.translucent = UINavigationBar.appearance().translucent
    navigationBar.shadowImage = UINavigationBar.appearance().shadowImage
  }
}
Zorayr
  • 22,104
  • 6
  • 124
  • 114
  • How can i show it again (for example if ill want to make it transparent only in 1 view in an NavigationController?) - can i reset it to my default values? – derdida Aug 07 '15 at 13:42
  • `hideTransparentNavigationBar()` should reset it back. – Zorayr Aug 07 '15 at 17:31
  • Calling present/hide methods in viewWillAppear/disappear cause a bad transition animation between the two differents navigation bar! You can see it very well by doing the swipe gesture (from left to right) in the pushedViewController – andreacipriani Sep 09 '15 at 14:07
  • Try calling it in `viewDidHide` of the parent view controller. – Zorayr Sep 09 '15 at 16:51
  • 1
    Black background is shown on iOS 11 when using LargeTitle when hiding transparent navbar – Vrutin Rathod Oct 12 '17 at 17:01
15

Alan forgot one line

self.navigationController.navigationBar.backgroundColor = [UIColor clearColor];

So I have:

[self.navigationController.navigationBar setTranslucent:YES];
self.navigationController.view.backgroundColor = [UIColor clearColor];
[self.navigationController.navigationBar setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault];
self.navigationController.navigationBar.shadowImage = [[UIImage alloc] init];
self.navigationController.navigationBar.backgroundColor = [UIColor clearColor];
Damien Romito
  • 9,262
  • 8
  • 62
  • 75
5

@Zorayr's great answer revised to Swift 3 :

import Foundation
import UIKit

extension UINavigationController {

    public func presentTransparentNavigationBar() {
        navigationBar.setBackgroundImage(UIImage(), for:.default)
        navigationBar.isTranslucent = true
        navigationBar.shadowImage = UIImage()
        setNavigationBarHidden(false, animated:true)
    }

    public func hideTransparentNavigationBar() {
        setNavigationBarHidden(true, animated:false)
        navigationBar.setBackgroundImage(UINavigationBar.appearance().backgroundImage(for: UIBarMetrics.default), for:.default)
        navigationBar.isTranslucent = UINavigationBar.appearance().isTranslucent
        navigationBar.shadowImage = UINavigationBar.appearance().shadowImage
    }
}
Diphaze
  • 91
  • 1
  • 4
3

Swift 4.2 and iOS 12

It turns out all you really need is the code below. It works perfectly when you put it into viewDidLoad().

// removes line at bottom of navigation bar
navigationController?.navigationBar.shadowImage = UIImage()

// makes navigation bar completely transparent
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationController?.navigationBar.isTranslucent = true
Trev14
  • 3,016
  • 2
  • 26
  • 34
-3

Use UINavigationBar+Addition pod, then simply call:

UINavigationBar *navigationBar = self.navigationController.navigationBar;
[navigationBar makeTransparent];
samwize
  • 23,611
  • 14
  • 136
  • 181
-4

[(UIView*)[self.navigationController.navigationBar.subviews objectAtIndex:0] setAlpha:0.0f];

That one line seemed to work perfectly for me