Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing navigation bar color while popping view controller

I have three view controllers. In the first view controller (FirstVC), the navigation bar's bar tint color is clearColor and the bar itself is translucent. When I click on something, I push to SecondVC where the navigation bar needs to be opaque. So I set the barTintColor to some color value and set isTranslucent to false. When I push to ThirdVC from SecondVC, the navigation bar again needs to be translucent. The issue arises when I pop the ThirdVC and go back to SecondVC. The navigation bar appears as transparent for a second and then becomes opaque as required. I'm unable to understand the reason for the delay.

The following method is called from viewWillAppear() of SecondVC. I have tried doing the same from the viewWillDisappear()of ThirdVC, but to no effect.

fileprivate func configureNavigationBar(){

        self.navigationController?.navigationBar.setBackgroundImage(nil, for: UIBarMetrics.default)
        self.navigationController?.navigationBar.shadowImage = nil
        self.navigationController?.navigationBar.isTranslucent = false
        self.navigationController?.navigationBar.barTintColor = Style.Movie.primaryBackgroundColor
        let titleDict: NSDictionary = [NSForegroundColorAttributeName: UIColor.white]
        self.navigationController?.navigationBar.titleTextAttributes = titleDict as? [String:Any]
    }

It works fine if I swipe back instead of tapping on the back button.

like image 496
StudentX Avatar asked Mar 06 '17 06:03

StudentX


2 Answers

use this function in thiredVC

override func willMove(toParentViewController parent: UIViewController?) {
          self.navigationController?.navigationBar.barTintColor = color use in secondVC
    }
like image 81
Hitesh Agarwal Avatar answered Oct 09 '22 15:10

Hitesh Agarwal


Came across this thread and came up with a nice solution to help all in the future.

Firstly create a custom UINavigationController with a type enum that will help define your navigation setups:

enum NavType: Int {
    case light, medium, dark
}

class NavigationController: UINavigationController {

    /* 
      Fetch the last controller in the navigation stack so the 
      ViewControllers can switch the navType
    */
    var previousController: ViewController? {
        if viewControllers.count > 1 {
            return viewControllers[viewControllers.count-2] as? ViewController
        }
        return nil
    }

    var navType: NavType = .light {
        didSet { updateNavType() }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        navigationBar.isTranslucent = false
        layoutNavigationTheme()
    }

    func layoutNavigationTheme() {
        switch navType {
        case .dark:
            view.backgroundColor = .white
            navigationBar.backgroundColor = .black
            navigationBar.barTintColor = .black
            navigationBar.tintColor = .white

        ... // Set up as per enum
        }
    }

}

Then create a custom UIViewController using the willMove(...:

class ViewController: UIViewController {

    var navType: NavType = .light

    var navigation: NavigationController? {
        return navigationController as? NavigationController
    }

    // Override willMove will fetch the last controller and set the navType
    override func willMove(toParentViewController parent: UIViewController?) {
        super.willMove(toParentViewController: parent)

        if let navigation = navigation {
            navigation.navType = navigation.previousController?.navType ?? .light
        }
    }

}

Then simply in your UIViewControllers, subclass your new ViewController and set the navType in the viewDidLoad:

class MainController: ViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        navType = .dark
    }

}
like image 5
RichAppz Avatar answered Oct 09 '22 17:10

RichAppz