4

I have problem with transparent screen inside other StackNagigation. demo

I want to show ScreenThree overlay in the front of ScreenTwo after click Go to ScreenThree button in ScreenTwo.

I have set cardStyle with backgroundColor: 'transparent' but it still doesn't working.

I dont know what's wrong here? Have anyone please help me?

import { StackNavigator } from 'react-navigation'; // 2.2.5


import React from 'react'
import { Image, View, Text, Button } from 'react-native'
import { StyleSheet, Dimensions, TouchableOpacity } from 'react-native'

export default class App extends React.Component {
  render() {
    return (
      <View style={{flex: 1, backgroundColor: 'red'}}>
        <Root/>
      </View>
    )
  }
}

class HomeScreen extends React.Component {

  render() {

    return (
      <View style={{
        backgroundColor: 'blue', 
        flex: 1, 
        justifyContent: 'center', 
        alignItems: 'center',
        paddingTop: 20
      }}>

      <TouchableOpacity onPress={
        () => { 
        this.props.navigation.navigate('ScreenTwo')}
      } 
      style={{
        padding: 16, 
        backgroundColor: 'gray'
      }}>
        <Text>
          Go to ScreenTwo
        </Text>
      </TouchableOpacity>
      </View>
      )
  }
}

class ScreenTwo extends React.Component {

  render() {

    return (
      <View style={{
        flex: 1, 
        justifyContent: 'center', 
        alignItems: 'center'
      }}>
        <Text style={{color: 'white'}}>
          ScreenTwo
        </Text>
        <TouchableOpacity onPress={
        () => { 
        this.props.navigation.navigate('ScreenThree')}
      } 
      style={{
        padding: 16, 
        backgroundColor: 'gray',
        marginTop: 16
      }}>
        <Text>
          Go to ScreenThree
        </Text>
      </TouchableOpacity>

      </View>
      )
  }
}

class ScreenThree extends React.Component {

  render() {

    return (
      <View style={{
        backgroundColor: 'rgba(0,0,0,0.3)', 
        flex: 1, 
        justifyContent: 'center', 
        alignItems: 'center'
      }}>
        <Text style={{color: 'white'}}>
          ScreenThree
        </Text>

      </View>
      )
  }
}

const DetailStack = StackNavigator({
  ScreenThree: {screen: ScreenThree}
}, {
  mode: 'modal',
    headerMode: 'none',
    cardStyle: {
      backgroundColor: 'transparent',
      shadowColor: 'transparent'
    },
})

const MainStack = StackNavigator({
  HomeScreen: {screen: HomeScreen},
  ScreenTwo: {screen: ScreenTwo},
DetailStack: {screen: DetailStack}
},
{
  headerMode: 'none',
  cardStyle: {shadowColor: 'transparent'},
})

const Root = StackNavigator({
  Main: {screen: MainStack}
},
{
    mode: 'modal',
    headerMode: 'none',
    cardStyle: {
      shadowColor: 'transparent'

    },
})
Ishara Madhawa
  • 3,549
  • 5
  • 24
  • 42
Sinh Phan
  • 1,180
  • 3
  • 16
  • 36

5 Answers5

6

I was having this issue too and took me a couple of days to find out why. There were 2 different factors:

  1. I was using the react-navigator v3 and cardStyle: { backgroundColor: 'transparent'} didn't help. So I had to go with the transparentCard: true
  2. Inspecting and modifying backgroundColor of the screen from the devtools would show all screen background to be transparent but they were still white. So what I found was that during screen transition, a container with white background is added to every screen on transition end (only happens in iOS and web).

    So, I had to set the background of this transition container to be transparent too -> Source code

transitionConfig: () => ({
  containerStyle: {
    backgroundColor: 'transparent'
  }
})

Another thing to note is you need to apply these 2 rules first to the very topmost navigator. Then you just modify the backgroundColor for whatever screen you want to be transparent or of other color :D

Bijay Timilsina
  • 757
  • 2
  • 10
  • 25
5

Paste this inside your ModalStackScreen. You can use this like a boiler plate.


<Stack.Navigator
  screenOptions={{
    headerShown: false,
    cardStyle: { backgroundColor: 'transparent' },
    cardOverlayEnabled: true,
    cardStyleInterpolator: ({ current: { progress } }) => ({
      cardStyle: {
        opacity: progress.interpolate({
          inputRange: [0, 0.5, 0.9, 1],
          outputRange: [0, 0.25, 0.7, 1],
        }),
      },
      overlayStyle: {
        opacity: progress.interpolate({
          inputRange: [0, 1],
          outputRange: [0, 0.5],
          extrapolate: 'clamp',
        }),
      },
    }),
  }}
  mode="modal"
>
  <Stack.Screen name="Home" component={HomeStack} />
  <Stack.Screen name="Modal" component={ModalScreen} />
</Stack.Navigator>

For more clarity/details read https://reactnavigation.org/docs/stack-navigator/ It's explained so well

3

In React-Navigation v6 it can be done with

https://reactnavigation.org/docs/stack-navigator/#transparent-modals

Like:

<Stack.Navigator>
  <Stack.Screen
    name="Modal"
    component={ModalScreen}
    options={{ presentation: 'transparentModal' }}
  />
</Stack.Navigator>
whalemare
  • 1,107
  • 1
  • 13
  • 30
0

This should give you what you're looking for

Update: transitionConfig needs to be a function and for my case I needed to add the empty screenInterpolator function.

const Root = StackNavigator({
  Main: {screen: MainStack}
},
{
    mode: 'modal',
    headerMode: 'none',
    cardStyle: {
      shadowColor: 'transparent'
    },
    transitionConfig: ({ scene }) => ({
      transitionSpec: {
        duration: 0,
        timing: Animated.timing,
        easing: Easing.step0,
      },
    screenInterpolator: screenProps => {
      return {}
    }
  })
})
mijota
  • 101
  • 1
  • 7
  • Currently working on a similar issue. Unfortunately this doesn't work, even when fixing `transitionConfig` (has to be a function, see [docs](https://reactnavigation.org/docs/en/stack-navigator.html)). – seasick Aug 06 '18 at 13:10
  • It does not work. This one works https://stackoverflow.com/questions/48992961/react-navigation-modal-height?rq=1 – Vince Yuan Oct 18 '18 at 11:02
0

This worked for me - Taken from this Github issue.

// create custom transitioner without the opacity animation, ie. for iOS
function forVertical(props) {
  const { layout, position, scene } = props;

  const index = scene.index;
  const height = layout.initHeight;

  const translateX = 0;
  const translateY = position.interpolate({
    inputRange: ([index - 1, index, index + 1]: Array<number>),
    outputRange: ([height, 0, 0]: Array<number>)
  });

  return {
    transform: [{ translateX }, { translateY }]
  };
}

// set it as the transitionConfig param on your stack navigator
const App = StackNavigator(
  {
    Modal: { screen: Modal }
  },
  {
    mode: "modal",
    headerMode: "none",
    transitionConfig: () => ({ screenInterpolator: forVertical })
  }
);
seasick
  • 473
  • 1
  • 4
  • 15