Skip to content

Support the default value of UIViewControllerBasedStatusBarAppearance (true) #11710

Closed

Description

@steipete

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

  1. ericvicenti commented on Jan 3, 2017

    @ericvicenti
    Contributor

    @ide, this may be related to your team's work on exponent view for iOS. Maybe you can tag whoever has the most context

  2. ide commented on Jan 4, 2017

    @ide
    Contributor

    @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.

  3. sophiebits commented on Jan 4, 2017

    @sophiebits
    Contributor

    StatusBar.setStyle

    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.

  4. ide commented on Jan 4, 2017

    @ide
    Contributor

    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.

  5. ericvicenti commented on Jan 4, 2017

    @ericvicenti
    Contributor

    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.

  6. ide commented on Jan 4, 2017

    @ide
    Contributor

    @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.

  7. ericvicenti commented on Jan 4, 2017

    @ericvicenti
    Contributor

    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.

    Totally agree!

    I have the exact same gripes with the <Modal> component

  8. sophiebits commented on Jan 4, 2017

    @sophiebits
    Contributor

    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…

  9. SudoPlz commented on Jun 21, 2017

    @SudoPlz
    Contributor

    Any news on that?

  10. hramos commented on Aug 24, 2017

    @hramos
    Contributor

    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:

    • Does the issue still reproduce on the latest release candidate? Post a comment with the version you tested.
    • If so, is there any information missing from the bug report? Post a comment with all the information required by the issue template.
    • Is there a pull request that addresses this issue? Post a comment with the PR number so we can follow up.

    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.

  11. steipete commented on Aug 24, 2017

    @steipete
    Author

    @hramos This is a conceptual issue and I have not seen a fix for it yet - please re-open this ticket.

  12. 17 remaining items

  13. stale commented on Feb 2, 2019

    @stale

    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.

  14. added
    StaleThere has been a lack of activity on this issue and it may be closed soon.
    on Feb 2, 2019
  15. fbartho commented on Feb 2, 2019

    @fbartho
    Contributor

    As far as I know, this is still an unsolved conceptual issue!

  16. steipete commented on Feb 2, 2019

    @steipete
    Author

    This issue is still unsolved. React Native needs to move to view controller based status bar management to be compatible with 3rd-party SDKs.

  17. stale commented on Feb 9, 2019

    @stale

    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.

  18. reopened this on Feb 9, 2019
  19. removed
    StaleThere has been a lack of activity on this issue and it may be closed soon.
    on Feb 9, 2019
  20. cpojer commented on Feb 15, 2019

    @cpojer
    Contributor

    This issue has been moved to rnc-archive/react-native-statusbar#5.

  21. locked as resolved and limited conversation to collaborators on Feb 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions