React-native-navigation: Status bar colour cannot be set for certain modal types

Created on 19 Dec 2019  ·  12Comments  ·  Source: wix/react-native-navigation

Issue Description

With certain modal presentation styles it is not possible to set the status bar colour. One example is currentContext, (the default mode?).

When commenting out the default modalPresentationStyle in the playground app you will see that the status bar colour for StatusBarOptionsScreen and FullScreenmodalScreen are dark, even though they were set to light. If the line in options is uncommented it works again.

Steps to Reproduce / Code Snippets / Screenshots

To reproduce in the playground app, apply the following diff:

────────────────────────────────────────────────────────────────────
modified: playground/src/commons/Options.js
────────────────────────────────────────────────────────────────────
@ Options.js:25 @ const setDefaultOptions = () => Navigation.setDefaultOptions({
  animations: {
    ...useSlowOpenScreenAnimations ? slowOpenScreenAnimations : {}
  },
  modalPresentationStyle: 'fullScreen'
  // modalPresentationStyle: 'fullScreen'
});

const slowOpenScreenAnimations = {
────────────────────────────────────────────────────────────────────
modified: playground/src/screens/FullScreenModalScreen.js
────────────────────────────────────────────────────────────────────
@ FullScreenModalScreen.js:19 @ class FullScreenModalScreen extends React.Component {
  static options() {
    return {
      statusBar: {
        visible: false
        style: 'light'
        // visible: false
      },
        topBar: {
        testID: MODAL_SCREEN_HEADER,
@ FullScreenModalScreen.js:37 @ class FullScreenModalScreen extends React.Component {
        <Button label='Show Modal' testID={MODAL_BTN} onPress={this.showModal} />
        <Button label='Dismiss Modal' testID={DISMISS_MODAL_BTN} onPress={this.dismissModal} />
        <Button label='Push' testID={PUSH_BTN} onPress={this.push} />
        <Button label='Dismiss Modal' testID={DISMISS_MODAL_BTN} onPress={this.dismissModal} />
      </Root>
    );
  }
────────────────────────────────────────────────────────────────────
modified: playground/src/screens/StatusBarOptionsScreen.js
────────────────────────────────────────────────────────────────────
@ StatusBarOptionsScreen.js:12 @ class StatusBarOptions extends React.Component {
  static options() {
    return ({
      statusBar: {
        translucent: true,
        drawBehind: true
        // translucent: true,
        // drawBehind: true,
        style: 'light'
      },
      topBar: {
        elevation: 0,
@ StatusBarOptionsScreen.js:47 @ class StatusBarOptions extends React.Component {
          <Button label='BottomTabs' onPress={this.bottomTabs} />
          <Button label='Open Left' onPress={() => this.open('left')} />
          <Button label='Open Right' onPress={() => this.open('right')} />
          <Button label='Dismiss modal' onPress={() => this.dismissModal()} />
        </Root>
      </View>
    );
@ StatusBarOptionsScreen.js:81 @ const style = StyleSheet.create({
  }
});

Environment

  • N.b. reproducible in playground app
  • React Native Navigation version: 4.0.5
  • React Native version: 0.60.4
  • Platform(s) (iOS, Android, or both?): Both
  • Device info (Simulator/Device? OS version? Debug/Release?): iOS 12 (possibly 13 too but I didn't test fullscreen modals there)
iOS acceptebug 📌 pinned

Most helpful comment

@Natteke Make sure UIViewControllerBasedStatusBarAppearance is set to YES in your info.plist file.

All 12 comments

I'm running into the same issue myself @LouiseBC .

It seems the status bar style can only be altered from the setDefaultOptions?
Using static options() {} I can't seem to get it to change.

This one breaks our upgrading to 0.61

Still exist on
React Native Navigation version: 6.0.1
React Native version: 0.61.5
(any layout)

Seems like style property is ignored when declared in static options @yogevbd

style option does work in static options, statusBar.visible isn't, fixed in https://github.com/wix/react-native-navigation/pull/5992.
If you still have issues with style property please let me know and explain how to reproduce it in the playground app.

@yogevbd, can you please provide example how to change statusbar color in latest version?
Just dont understand how to do it

Thanks a lot!

@Natteke The StatusBar appearance is controlled through options.

For example, the following options will change the StatusBar background color to white will use dark colors for the StatusBar content (time, battery information, notification icons etc)

options: {
  statusBar: {
    backgroundColor: 'white',
    style: 'dark'
  }
}

⚠️ React native's StatusBar component is incompatible with React Native Navigation and you should avoid using it.

Changing StatusBar style dynamically

As the StatusBar is controlled through options, it can be configured dynamically by calling Navigation.mergeOptions with the desired StatusBar options.

For example, here's how you would hide the StatusBar dynamically

Navigation.mergeOptions(this.props.componentId, {
  statusBar: {
    visible: false
  }
});

@guyca, take a look at this, here i provided example that this approach does not work, style property just ignored on IOS. Or it's because i dont provided backgroundColor property?

Maybe i misunderstood something?
Btw, thanks for quick response. Much appreciated!

@Natteke Make sure UIViewControllerBasedStatusBarAppearance is set to YES in your info.plist file.

@yogevbd, yes! It was sat "false" by default. Now it’s working! Thanks!

For RN newcomers this could be not obvious, and looks like link script do not changing it.

Maybe we could mention this in the doc?
In the manual installation for example...
I could make a PR with it.

@yogevbd, I'm on [email protected], [email protected] and it doesn't work on iOS 13.3. UIViewControllerBasedStatusBarAppearance was set to NO, but changing it to YES doesn't help. visible in static options of modal screen is ignored on iOS, but working fine on Android.

Here is an example:

 static options(passProps) {
    return {
      ...defaultStyles,
      topBar: {
        drawBehind: true,
        background: {
          color: '#00000044'
        }
      },
      modalPresentationStyle: 'overCurrentContext',
      statusBar: {
        visible: false
      }
    }
  }

Am I missing something?

@xvonabur Try setting modalPresentationStyle to currentContext. I had the same issue where I set modal presentationStyle to overFullScreen and fixed it by setting it to fullScreen.

Was this page helpful?
0 / 5 - 0 ratings