React-native-screens: [native-stack] iOS 13 Style Modal Has White Background instead of Black

Created on 22 Feb 2020  ·  14Comments  ·  Source: software-mansion/react-native-screens

_Moved from react-navigation/react-navigation#6791. Originally opened by @hammadj_


Current Behavior

  • What code are you running and what is happening?
    Using a NativeStackNavigator and presenting a screen with stackPresentation: 'modal' results in the app having a white BG.
    Screen Recording 2020-02-06 at 12 15 20 AM

Expected Behavior

  • What do you expect should be happening?
    The status bar text should turn white and the background should be black:
    RPReplay_Final1580973117

How to reproduce

Using Expo SDK 36, with backgroundColor in app.json set to #000000 it still doesn't work.

Here's the code snippet:

const Stack = createNativeStackNavigator<NavScreenParams>();

export const HomeNavigator: React.FC = () => (
  <Stack.Navigator initialRouteName={Screen.HOME}>
    <Stack.Screen
      name={Screen.HOME}
      component={Home}
      options={{ title: 'Home', headerShown: false }}
    />
    <Stack.Screen
      name={Screen.PROFILE}
      component={ProfileNavigator}
      options={{ stackPresentation: 'modal' }}
    />
  </Stack.Navigator>
);

Your Environment

| software | version |
| ------------------------------ | ------- |
| iOS or Android | iOS
| @react-navigation/native | 5.0.0
| @react-navigation/native-stack | 5.0.0
| react-native-screens | 2.0.0-beta.2
| react-native | https://github.com/expo/react-native/archive/sdk-36.0.0.tar.gz
| expo | 36.0.2
| node | 10.16.0
| npm or yarn | 1.16.0

native-stack

Most helpful comment

Setting up at navigator level with cardOverlayEnabled set to true is getting the right background colour with expo sdk37:

<Stack.Navigator
    headerMode="none"
    mode="modal"
    screenOptions={{
        gestureEnabled: true,
        cardOverlayEnabled: true,
        ...TransitionPresets.ModalPresentationIOS,
    }}
>
    //Stack.Screens goes here
</Stack.Navigator>

All 14 comments

Could you try „transparentModal“ instead of Modal in Version 2.2.0 and report back? @hammadj

Same here

Could you try „transparentModal“ instead of Modal in Version 2.2.0 and report back? @hammadj

I have this code

`const Stack = createStackNavigator();

const headerStyle = {
elevation: 0,
shadowOpacity: 0,
height: 100,
};

function RootStack() {
const login = {
title: '',
headerStyle,
headerShown: Platform.OS !== 'ios',
headerLeft: () => ,
cardOverlayEnabled: true,
...TransitionPresets.ModalPresentationIOS,
};

const app = {
title: '',
headerShown: false,
animationEnabled: false,
};

return (





name="Tutorial"
component={Tutorial}
options={{
headerShown: false,
animationEnabled: false,
}}
/>







);
}`

"react-native-screens": "2.3.0",

I'm using and experiencing the same issue:
Not sure how to set the overlay options.
my nmp package: "react-native-screens": "^2.3.0",

// Navigation.tsx
import {createNativeStackNavigator} from "react-native-screens/native-stack";
const RootStackNative = createNativeStackNavigator();

interface AppNavigationProps {
  native?: boolean;
}

function AppNavigation({native = true }: AppNavigationProps) {
  return (
        <RootStackNative.Navigator screenOptions={{ stackPresentation: "modal" }}>
          <RootStackNative.Screen
            name='Main'
            component={MainStackScreen}
            options={{ headerShown: false }}
            initialParams={{ native }}
          />
          <RootStackNative.Screen
            name='Search'
            component={SearchModal}
            options={{
              headerShown: false,
            }}
            initialParams={{ native }}
          />
        `</RootStackNative.Navigator>`
      );
}

export default function Navigation(props: NavigationProps) {
  const { data, loading, error } = useMeQuery({ context: { useApolloNetworkStatus: false } });

  if (loading) {
    return <Loading />;
  }

  return (
    <NavigationContainer>
      <AppNavigation
        native
      />
    </NavigationContainer>
  );
}

image

transparentModal doesn't seem to give me the same behavior as it doesn't push away the view below., It just slides the new screen up.

I'm currently working on exposing a way to customize status bar from stack header options. This is not ready yet and I'll update here on the status.

In the meantime wanted to share some solutions you may try right now:

1) The background color that you see under the new iOS 13 modal is the application window background. Apparently expo sets that to be white. If your app is ejected from expo (or use bare workflow) you should be able to change that in appdelegate by doing self.window.backgroundColor = [UIColor blackColor]; after the window is initialized. Note this will change the background for the whole app and won't allow you to update that background at will (unless you write a native module to update it)

2) The status bar color below the modal should be handled automatically by the system. However that behavior is likely disabled if you use standard react-native or expo project. To enable automatic handling of status bar color you'll need to update Info.plist setting UIViewControllerBasedStatusBarAppearance to YES. The reason why it is set to NO is for the RN's StatusBar module to work. The status bar module allows for overriding status bar style but it requires that option to be disabled. If you change it to YES you will no longer be able style the status bar using StatusBar module from react native. Flipping it to YES however will give you the exact effect as in the first post here where the status bar color animates as the modal opens.

@kmagiera could we maybe allow setting the background color from the app.json like it's implemented for the splash screen?
Also is this something that @brentvatne is looking into?
https://github.com/expo/expo/issues/6585

yes, this is the same issue. There is a setting in app.json for the background color, however it sets the color for the root view while the new iOS modal displays over the rootview revealing fragments of the window which has a white background set on expo shell.

Setting up at navigator level with cardOverlayEnabled set to true is getting the right background colour with expo sdk37:

<Stack.Navigator
    headerMode="none"
    mode="modal"
    screenOptions={{
        gestureEnabled: true,
        cardOverlayEnabled: true,
        ...TransitionPresets.ModalPresentationIOS,
    }}
>
    //Stack.Screens goes here
</Stack.Navigator>

This issue has been fixed with the lastet SDK 37 patch-release. Just set the color in your app.json - it also works for native-stack

@Hirbod Just gave it a try. Doesn't seem to work when the stack containing the modal is not the root stack. At least in my case. Unless I'm missing something?

Make sure u pass a theme to your <NavigationContainer> which can contain a background color. Set backgroundColor in your app.json (expo.backgroundColor) or set it in your platform (expo.ios.backgroundColor)

Having trouble with this and cannot find the bug. Using expo 37.0.12, and react-navigation 5, react-native-screens 2.8.0.
Have set the backgroundColor in app.sjon, and in the navigatorTheme.

It works with the stack navigator from react-navigation, but don't think that says anything.

UPDATE: it works when building, but not within the expo client app.

@CruelMoney - please share a mcve. everything works as expected for me.

I am closing it due to no response in more than 30 days. Feel free to comment to reopen it.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jeveloper picture jeveloper  ·  5Comments

harrisrobin picture harrisrobin  ·  3Comments

chai86 picture chai86  ·  3Comments

beetlebum picture beetlebum  ·  5Comments

chengsokdara picture chengsokdara  ·  3Comments