Search code examples
iosswiftios-statusbar

What should be the best way to change StatusBar background colour and preferredStatusBarStyle?


My requirements are like, in my app there are two flows, so for both flows value of preferredStatusBarStyle & StatusBar background colour are different. So if I have 40 viewControllers, 20 VCs have same values and 20VCs have different values than first 20 values.

For now I am changing values in each view controllers, like this:-

override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

override func viewDidLoad() {
    super.viewDidLoad()

    UIApplication.shared.statusBarView?.backgroundColor = AppColors.themeStatusColor
}

and in info.plist I did this:-

<key>UIViewControllerBasedStatusBarAppearance</key>
<true/>

Can u guys tell me any way so I can write these lines of code only two places and I can achieve my requirements.


Solution

  • class BaseVCBlue: UIViewController {
    
    override var preferredStatusBarStyle: UIStatusBarStyle {
        return UIStatusBarStyle.default
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        self.setNeedsStatusBarAppearanceUpdate()
        UIApplication.shared.statusBarView?.backgroundColor = UIColor.white
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
    
        self.setNeedsStatusBarAppearanceUpdate()
    }
    }
    
    
    
    class BaseVc: UIViewController {
    
    override var preferredStatusBarStyle: UIStatusBarStyle {
        return UIStatusBarStyle.lightContent
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        UIApplication.shared.statusBarView?.backgroundColor = AppColors.themeStatusColor
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
    
        self.setNeedsStatusBarAppearanceUpdate()
    }
    

    But Most important one:- There’s one case where this won’t work and that is if your controller is embedded in a navigation stack 😒. Reason being that iOS wants the parent controller (and NOT the child controller) to decide what kind of status bar one needs to show, then do this also:-

    extension UINavigationController {
        open override var preferredStatusBarStyle: UIStatusBarStyle {
            return topViewController?.preferredStatusBarStyle ?? .default
        }
    }
    

    Now u can change easily and this will work perfectly :)