Cole James
Cole James

Reputation: 230

How to change Navigation Bar back to translucent after making it transparent

I have a view controller in my navigation stack that needs to have a transparent navigation bar, while still showing the back button.

I'm able to achieve that with one line of code inside viewWillAppear:

self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)

However, when I try to go back to the previous view, I'm setting the background image back to nil or .none but I'm losing the translucent effect that was previously on there when I do that.

I've tried setting all the following options in viewWillDisappear and none seem to bring the translucency back. It just appears white no matter what I do. The shadow on the bottom is also gone too:

self.navigationController?.navigationBar.isTranslucent = true
self.navigationController?.navigationBar.barStyle = .default
self.navigationController?.navigationBar.backgroundColor = .none
self.navigationController?.navigationBar.setBackgroundImage(.none, for: .default)

Initial Navigation Bar:

Initial Navigation Bar

Transparent Navigation Bar:

Transparent Navigation Bar

After Transitioning Back:

After Transitioning Back

Upvotes: 2

Views: 2101

Answers (3)

Wendell
Wendell

Reputation: 546

This worked for my app which needs to revert to an opaque navigation bar after popping from a transparent navigation bar.

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    navigationController?.navigationBar.setBackgroundImage(nil, for: .default)
    navigationController?.navigationBar.shadowImage = nil
    navigationController?.navigationBar.isTranslucent = true
    navigationController?.navigationBar.backgroundColor = nil
}

Upvotes: 0

Jiropole
Jiropole

Reputation: 174

After spending time poking around in the UINavigationBar internals, I did discover a simple method that seems to work, and does not require any configuration of the standard UINavigationBar attributes we've previously fiddled with to achieve transparency. The following is tested working on iOS 12.2.x:

class TallNavigationBar: UINavigationBar {

    private lazy var maskingView: UIView = {
        let view = UIView(frame: bounds)
        view.backgroundColor = .clear
        return view
    }()

    var isTransparent = false {
        didSet {
            guard isTransparent != oldValue, let bkgView = subviews.first else { return }

            bkgView.mask = isTransparent ? maskingView : nil
        }
    }
}

Obviously, whenever fiddling (even slightly) with undocumented internals: use at your own risk!

Upvotes: 0

RajeshKumar R
RajeshKumar R

Reputation: 15748

In viewWillAppear make the navigation bar transparent

override func viewWillAppear(_ animated: Bool) {        self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
    self.navigationController?.navigationBar.shadowImage = UIImage()
    self.navigationController?.navigationBar.isTranslucent = true
}

And backg to translucent in viewWillDisappear

override func viewWillDisappear(_ animated: Bool) {
    self.navigationController?.navigationBar.setBackgroundImage(nil, for: .default)
    self.navigationController?.navigationBar.shadowImage = nil
    self.navigationController?.navigationBar.isTranslucent = false
}

Upvotes: 1

Related Questions