Repository navigation
Description
Description
React Native currently requires that UIViewControllerBasedStatusBarAppearance is set to NO. This is an app-global setting and Apple offers this to help bringing old (pre-iOS 7) apps over to newer OS versions. It's not recommended that this is set for new apps. The methods for manual status bar control are already deprecated and Apple explicitly discourages using them:
To opt out of the view controller-based status bar appearance behavior, you must add the UIViewControllerBasedStatusBarAppearance key with a value of false to your app’s Info.plist file, but doing so is not recommended.
https://developer.apple.com/reference/uikit/uiapplication/1622923-setstatusbarstyle#discussion
The check was added in 2015:
https://github.com/facebook/react-native/blame/64a4c6070df7e711e7fd01c490f369bbd0d0fb28/React/Modules/RCTStatusBarManager.m#L109-L111
At PSPDFKit we offer a React Native module. We also have a very similar check that warns if the value of UIViewControllerBasedStatusBarAppearance is still set to the old behavior.
https://pspdfkit.com/blog/2016/react-native-module/
Here's our FAQ article about it:
https://pspdfkit.com/guides/ios/current/faq/uiviewcontrollerbasedstatusbarappearance/
Other platforms (Xamarin) are switching to the new style as well:
xamarin/Xamarin.Forms#463
Reproduction
See the code check for UIViewControllerBasedStatusBarAppearance. React should either support both or just default to the non-deprecated style. Currently any modification of the status bar requires this key to be set to false (true is the default)
Solution
This is tricky. See the related discussion on Twitter with Nick who wrote the original check:
https://twitter.com/nicklockwood/status/816334935422337025
I realize that React doesn't own the parent View Controller. There are still quite a few ways how the parent VC can be accessed and how hooks could be installed to both have the current flexibility (so we do not break any API) and offer compatibility with the new way of controlling the status bar.
I am willing to help and work on this but I'd first love to hear if there are any discussions around this that I missed while searching for it and what the mid- to long-term plans here are. I know that everything related to the status bar on iOS is painful, so I'm apologizing in advance for bringing up this issue.
Additional Information
- React Native version: 0.39
- Platform: iOS
- Operating System: MacOS
Activity
ericvicenti commentedon Jan 3, 2017
@ide, this may be related to your team's work on exponent view for iOS. Maybe you can tag whoever has the most context
ide commentedon Jan 4, 2017
@ericvicenti We'd probably want to come up with whatever API makes sense for RCTRootView and then can expose a similarly structured API through ExponentView.
@steipete I haven't heard of any discussions about this since the original method works fine in most cases but I do think it's a good idea to be ready for when they finally do remove these APIs. There is a class called RCTRootViewDelegate that the programmer could hook up to the owning VC and we could add a method like
reactRootViewDidRequestStatusBarStyleChange.The tricky part is that an app can have multiple RCTRootViews per RCTBridge (the true core of React Native). I think the naive solution is for calls to
StatusBar.setStyle(whatever)to be fed through the bridge to all RCTRootViews and up through each of their delegates, i.e. broadcast the status bar change to all owning VCs. I believe this would mostly match the semantics of the current API and globally change the status bar.We probably do want to keep the deprecated API for now in case one of Facebook's apps uses it, if we break a FB app the commit is just going to be reverted.
sophiebits commentedon Jan 4, 2017
Didn't Apple introduce VC-based status bar control since global imperative calls to set the status bar state were too unwieldy? :) Maybe what we need is a RCTRootViewController for full-screen views and a declarative way to request a status bar appearance in JS where it's clear what takes precedence in the case of a conflict.
ide commentedon Jan 4, 2017
We still need an imperative way to change the status bar style for the current VC, whether that's an RCTRootViewController or just any UIViewController that conforms to RCTRootViewDelegate. I prefer the latter to keep the API surface area of RN more flexible.
Most RN apps are housed under one RCTRootView (and therefore one VC) so we do need a way to request status bar changes. They have to be imperative at the Obj-C level I think because all bridge calls are imperative. Navigation libraries can then wrap the imperative call in a declarative API in user space.
ericvicenti commentedon Jan 4, 2017
Yep, at some point every API needs to be imperative. I never really understood why we decided to make a status bar component- because the behavior can be totally unexpected when there are multiple StatusBar components in the hierarchy but only one global status bar to control. I think it is a pretty safe bet to treat a app-global API like a global API for our JS app.
ide commentedon Jan 4, 2017
@ericvicenti I agree, I find the current StatusBar component short-sighted. Thinking about tab bars and drawers and other navigation paradigms, there are many cases where there are two scene components mounted on-screen at the same time and you can toggle between which one is "active". React has no notion of the "active" screen but the navigation API does -> react-navigation is the right level of abstraction to expose a status bar component or prop.
ericvicenti commentedon Jan 4, 2017
Totally agree!
I have the exact same gripes with the
<Modal>componentsophiebits commentedon Jan 4, 2017
Well, it would be nice long-term if we can clearly delineate which are best avoided in structured applications – or else people will surely use the imperative one even when they should be using a navigation-based one. You know how people are…
SudoPlz commentedon Jun 21, 2017
Any news on that?
hramos commentedon Aug 24, 2017
Hi there! This issue is being closed because it has been inactive for a while. Maybe the issue has been fixed in a recent release, or perhaps it is not affecting a lot of people. Either way, we're automatically closing issues after a period of inactivity. Please do not take it personally!
If you think this issue should definitely remain open, please let us know. The following information is helpful when it comes to determining if the issue should be re-opened:
If you would like to work on a patch to fix the issue, contributions are very welcome! Read through the contribution guide, and feel free to hop into #react-native if you need help planning your contribution.
steipete commentedon Aug 24, 2017
@hramos This is a conceptual issue and I have not seen a fix for it yet - please re-open this ticket.
17 remaining items
Expose static methods to manipulate the StatusBar stack imperatively (#…
stale commentedon Feb 2, 2019
Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as "For Discussion" or "Good first issue" and I will leave it open. Thank you for your contributions.
fbartho commentedon Feb 2, 2019
As far as I know, this is still an unsolved conceptual issue!
steipete commentedon Feb 2, 2019
This issue is still unsolved. React Native needs to move to view controller based status bar management to be compatible with 3rd-party SDKs.
stale commentedon Feb 9, 2019
Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please feel free to create a new issue with up-to-date information.
cpojer commentedon Feb 15, 2019
This issue has been moved to rnc-archive/react-native-statusbar#5.