Not all pages in iOS will have an action bar, but it is often necessary to change the status bar color on these pages. However, in the current implementation, that does not seem to be possible.
Without an Action Bar, setting the navigation bar style has no effect:
// Does nothing when the action bar is hidden
topmost().ios.controller.navigationBar.barStyle = UIBarStyle.Black
And using the page.backgroundSpanUnderStatusBar (as described here) does not work either, regardless of what the background color of the page is set to. (The source doesn't even appear to use this property anywhere at all).
What we really need is a property that can be set on a Page that will change the return value of preferredStatusBarStyle (and call setNeedsStatusBarAppearanceUpdate so that the ui updates properly). Otherwise, there's nothing that can be done to set the status bar color on a page that does not have an action bar.
Hi @JWiseCoder,
In your scenario, you can use nativescript-statusbar plugin, which allows you to change the StatusBar color on the page.
That is not sufficient. I don't merely want to change the background color of the status bar. That is not how native iOS works, and it is not how it is meant to be used. I have pages with light and dark backgrounds, and I don't want the status area showing up in a bar like we're back in iOS 6.
Even if there were a way to implement a custom UIViewController implementation for a page (basically extending UIViewControllerImpl), that'd be fine. Better than that would be a property that could set the preferredStatusBarStyle of UIViewControllerImpl.
Either way, there really needs to be a way to do this so that the app behaves as much like a native app as possible.
Hi @JWiseCoder,
In your scenario, you can use nativescript-statusbar plugin, which allows you to change the StatusBar color on the page.
This only works in iOS for pages that have Action Bars. The plugin says as much in its documentation, and it's obvious from the code that that's how it works.
There needs to be a way to set the status bar style without an ActionBar, like a login screen.
Hi @JWiseCoder,
Thank you for the additional info. Indeed the plugin will change the StatusBar style, only when the ActionBar is defined in the page. In my opinion, this scenario should be handled by the existing plugin, which already provides the functionality to style the StatusBar. I would suggest opening a new feature request in the plugin's repository, where you can describe your use-case as well.
That's just the problem: it's impossible to implement given the current NativeScript implementation. I could write the necessary code myself were I able to override the UIViewControllerImpl (found in page.ios.ts). I've done quite a lot of development for native iOS apps, and this seems to be the only way to do this inside NativeScript, as far as I can tell. And I don't see any way that a plugin could add the proper functionality.
That is why I opened this new feature request, because as far as I can tell, this is the only way to add this functionality.
@JWiseCoder finally, do you managed to solve it? I'm trying to set a dark status bar with white text color. For the moment, I only managed to set a dark status bar using nativescript-statusbar, but with dark text color :disappointed:
Thanks!
Create a hidden action bar like so:
<actionBar title="cheese" height="0" opacity="0" />.
Then you can mess around with the status colour like normal..
var navController = frame.topmost().ios.controller;
var navigationBar = navController.navigationBar;
navigationBar.barStyle = UIBarStyle.Black;
Took me quite a long time to workout :L
The above brakes when you switch apps and switch back again. I found an even better solution and wrote it down here:
https://stackoverflow.com/questions/57555115/how-to-change-the-status-bar-color-in-ios-without-an-actionbar-in-nativescript#57555116
@7ammer: You're using setStatusBarStyle which is deprecated on UIApplication.
@npulidom: The only way I found to get it to work was to override the prototype of UIViewController. I don't recommend this as a solution, but it does work, provided you can set _preferredStatusBarStyle on the correct view controller. This can be difficult when using a side drawer or anything else that messes with the view controller hierarchy.
if (isIOS) {
Object.defineProperty(UIViewController.prototype, 'preferredStatusBarStyle', {
get: function () {
return this._preferredStatusBarStyle || UIStatusBarStyle.Default;
},
enumerable: true,
configurable: true
});
}
Also, whenever you set _preferredStatusBarStyle on a view controller, then you have to call setNeedsStatusBarAppearanceUpdate() on that same view controller.
Hey @JWiseCoder,
I'm using a method called setStatusBarStyleAnimated. Are you saying that it _actually_ calls this method: https://developer.apple.com/documentation/uikit/uiapplication/1622923-setstatusbarstyle?
If so that sucks :(
@7ammer: Yes, that's correct. That's the same function. Setting status bar properties through UIApplication has been removed in favor of being able to set them individually on each view controller.
In native code, you have to use the preferredStatusBarStyle read-only property. The real solution is for the nativescript implementations to expose a property that hooks into preferredStatusBarStyle
It looks like over-riding preferredStatusBarStyle was implemented here in NativeScript Core.
I am now able to change the status bar text color by calling
page.statusBarStyle = "light"
or
page.statusBarStyle = "dark"
Most helpful comment
That is not sufficient. I don't merely want to change the background color of the status bar. That is not how native iOS works, and it is not how it is meant to be used. I have pages with light and dark backgrounds, and I don't want the status area showing up in a bar like we're back in iOS 6.
Even if there were a way to implement a custom UIViewController implementation for a page (basically extending
UIViewControllerImpl), that'd be fine. Better than that would be a property that could set thepreferredStatusBarStyleofUIViewControllerImpl.Either way, there really needs to be a way to do this so that the app behaves as much like a native app as possible.