Nikita Zernov
Nikita Zernov

Reputation: 555

Transparent UINavigationBar in Swift

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.

Upvotes: 33

Views: 57474

Answers (6)

Ashish Kakkad
Ashish Kakkad

Reputation: 23882

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

Upvotes: 119

Alexander Stepanishin
Alexander Stepanishin

Reputation: 494

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.

Upvotes: 0

user550088
user550088

Reputation: 722

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
    }
}

Upvotes: 5

Ankit Kumar Gupta
Ankit Kumar Gupta

Reputation: 4042

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
    }
} 

Upvotes: 5

Jeff Gu Kang
Jeff Gu Kang

Reputation: 4889

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
}

Upvotes: 6

Chamath Jeevan
Chamath Jeevan

Reputation: 5172

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

Upvotes: 32

Related Questions