33

I am trying to make my UINavigationBar in UINavigationController transparent. I created a subclass of UINavigationController and liked it to a scene in my storyboard file. Here's a piece of my subclass:

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.
    let size = self.navigationBar.frame.size
    self.navigationBar.setBackgroundImage(imageWithColor(UIColor.blackColor(), size: size, alpha: 0.2), forBarMetrics: UIBarMetrics.Default)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func imageWithColor(color: UIColor, size: CGSize, alpha: CGFloat) -> UIImage {
    UIGraphicsBeginImageContext(size)
    let currentContext = UIGraphicsGetCurrentContext()
    let fillRect = CGRectMake(0, 0, size.width, size.height)
    CGContextSetFillColorWithColor(currentContext, color.CGColor)
    CGContextSetAlpha(currentContext, alpha)
    CGContextFillRect(currentContext, fillRect)
    let retval: UIImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return retval
}

When I run my application a have a navigation bar transparent, but status bar is just black.

For example if I do such thing on UITabBar - it works.

Nikita Zernov
  • 545
  • 1
  • 5
  • 5

6 Answers6

120

Hope it help you

Swift 2:

self.navigationController.navigationBar.setBackgroundImage(UIImage(), forBarMetrics: UIBarMetrics.Default)
self.navigationController.navigationBar.shadowImage = UIImage()
self.navigationController.navigationBar.isTranslucent = true
self.navigationController.view.backgroundColor = UIColor.clearColor()

Swift 4.2 to Swift 5.1

self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.isTranslucent = true
self.navigationController?.view.backgroundColor = UIColor.clear

Or If you want to sublcass the navigation controller then refer this answer.


Change the status bar style via :

In your Info.plist you need to define View controller-based status bar appearance to any value.

enter image description here

UIApplication.shared.statusBarStyle = .lightContent

If you want to hide the status bar:

UIApplication.shared.isStatusBarHidden = true

Getting this output by light content and by transparent navigation. I have view background is gray. you can see the transparency.

enter image description here

iPhone XR - Swift 4.2 - Large Titles (Test Screenshot)

Large Titles - Swift - iPhone XR

Ashish Kakkad
  • 23,586
  • 12
  • 103
  • 136
32

If you're using Swift 2.0 uses the code block below:

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

For Swift 3.0 use:

navigationController?.setNavigationBarHidden(false, animated: true)
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
navigationController?.navigationBar.shadowImage = UIImage()
navigationController?.navigationBar.isTranslucent = true
shim
  • 9,289
  • 12
  • 69
  • 108
Chamath Jeevan
  • 5,072
  • 1
  • 24
  • 27
6

Swift 3.0.1 with Xcode 8.1

In your UINavigationController

override func viewDidLoad() {
    super.viewDidLoad()
    self.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
    self.navigationBar.shadowImage = UIImage()
    self.navigationBar.isTranslucent = true
    self.view.backgroundColor = UIColor.clear
}
Jeff Gu Kang
  • 4,749
  • 2
  • 36
  • 44
5

Xcode 8.x : Swift 3: Extension for the same Write once use throughout

extension UINavigationBar {

    func transparentNavigationBar() {
        self.setBackgroundImage(UIImage(), for: .default)
        self.shadowImage = UIImage()
        self.isTranslucent = true
    }
} 
Ankit Kumar Gupta
  • 3,994
  • 4
  • 31
  • 54
5

Create an extension of UINavigationController and present or hide transparent navigation bar.

extension UINavigationController {

    public func presentTransparentNavigationBar() {
        navigationBar.setBackgroundImage(UIImage(), for:UIBarMetrics.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:UIBarMetrics.default)
        navigationBar.isTranslucent = UINavigationBar.appearance().isTranslucent
        navigationBar.shadowImage = UINavigationBar.appearance().shadowImage
    }
}
gkubed
  • 1,849
  • 3
  • 32
  • 45
user550088
  • 712
  • 1
  • 8
  • 16
  • This is not correct, calling `setNavigationBarHidden` will also hide back button and navigation item, that's not what OP wants – Adam Aug 04 '20 at 08:39
0

I tried all methods above and still got white space instead of content that supposed to be rendered through. If you want to draw regular subview (Google map f.e.), not UIScrollView content through navigation bar, then you need to set subview's frame in viewDidAppear. So step 1:

existingNavigationBar.setBackgroundImage(transparentImageFromAssets, for: .default)
existingNavigationBar.shadowImage = transparentImageFromAssets
existingNavigationBar.isTranslucent = true

step 2:

override func viewDidAppear(_ animated: Bool) {
      super.viewDidAppear(animated)
      self.mapView.frame = UIScreen.main.bounds
  }

This worked for me.

Jaydeep Vora
  • 6,085
  • 1
  • 22
  • 40