iOS — Status bar colour (light / dark)
Hello Devs, this short article, about setting up the status bar colour for your iOS app might help you in your app development process. Lets jump into it.
Do want your status bar to be one single colour across your app, or do you want it to change based on the current visible screen (ViewController) ? we will consider both cases!
You have two options now:
(1) Set status bar once across your app
(2) Set status bar based on your visible screen
If you jump into your info.plist file of your project, and add a new property or watch out for existing ones, you’ll find a property named:
This plays the key role here. If it is set to false (NO) your app will adapt the status bar style as set in your project > targets > general > status bar style. This will be applied universally across your app irrespective of any visible screen.
If it is set to true (Yes) the app will then ask visible screen whether or not it has a preferredStatusBarStyle property overridden in it. If the property is overridden, and returns a specific value, the status bar then adapts that value. If the property is not overridden in it, then that value from status bar style from general tab of project is adapted.
The above property has three possible values i.e. default, lightContent and darkContent. lightContent is the default value when your phone is set to dark mode, and darkContent is the default value when your phone is set to light mode in your os.
For the first case, i.e. setting your status bar colour once across the app, just set this (view controller based status bar appearance to ‘NO’) in the info.plist file, and set your status bar style in project > targets > general > status bar style. Simple, straight forward.
Now for the second one, here are some use cases for understanding how this works. I faced some of these during a real project implementation, therefore sharing this might save you some time. (make sure view controller based status bar appearance is set to true (YES) in the info.plist file)
Example cases: (3 cases)
(1) You have simple ViewController launched right after the launch screen in your project.
Discussion: This is the simplest case, all you have to do is override preferredStatusBarStyle in your ViewController class, and return a desired value in it. This will work smooth.
(2) You have ViewController which is embedded inside a navigation controller.
Discussion: For this case, if you did overridden the preferredStatusBarStyle in your ViewController, you are very soon going to notice that this isn’t working anymore. Reason behind this is, that the navigation controller in now being checked by your app that whether it has overridden preferredStatusBarStyle or not. If the property is not overridden it would take that one from project > targets > general > status bar style and will not check view controllers in it’s stack for above overridden property.
This took my time, and for a while I was unable to find out, why my ViewController is not picking up the status bar style even I did override the preferredStatusBarStyle in it.
Now you say, that you have to use the different status bar style for every individual screen that is pushed or popped from your navigation controller stack. Here, is the workaround for this:
override var preferredStatusBarStyle: UIStatusBarStyle {
if let vc = viewControllers.last
{ return vc.preferredStatusBarStyle }
else
{ return .default }
}
This piece of code is going inside your custom navigation controller class. By doing this you are returning the preferredStatusBarStyle of your last visible view controller that is inside your navigation stack. Great now override preferredStatusBarStyle in your ViewController classed and this will now work smooth.
(3) You have some ViewControllers which are embedded inside a tab bar controller.
Discussion: Nah nah, don’t expect the same from tab bar controller as it worked for navigation controller. For this case, your tab bar controller does ask your view controller whether it has a preferredStatusBarStyle or not. Overriding the preferredStatusBarStyle in your tab bar controller class won’t effect this case.
Override this property directly as you did for first case, it will work smooth. But suppose you have navigation controller as the view controller associated with one or more of your tabs of tab bar controller. For this scenario, the tab which has the navigation controller, case 2 will work, preferredStatusBarStyle from navigation controller will come into action. And you already know how to handle that.
Lastly, I have presented the view controllers by overriding this property in view controllers, and it does not take effect for any presented view controller.
It would be great to listen to any additional information. Happy coding :)