React native render view over navigation bar

Viewed 2148

I have an app with react-navigation where I want to draw over navigation bar. My app.js looks like this:

export default class App extends React.Component {
    render() {
        return (
            <Provider store={store}>
                <StatusBar barStyle='dark-content'></StatusBar>
                <Navigation />
            </Provider>
        )
    }
}

...
const AppNavigator = createStackNavigator({
    Home: HomeView,
    Detail: DetailView
},

let Navigation = createAppContainer(AppNavigator)

In HomeView which is the root component, my render method looks like this:

    render() {
        return (
             <View style={{ flex: 1, backgroundColor: colors.backgroundColor }}>

                  {isModalVisible && <View style={styles.overlay}>
                                          ... Modal content
                                     </View>}
                  ... Other views
             </View>
        )
    }

overlay: {
    position: 'absolute',
    zIndex: 1,
    top: 0,
    left: 0,
    width: Dimensions.get('screen').width,
    bottom: 0,
    backgroundColor: '#000000A0',
},

My problem is that, the modal view doesn't render over navigation bar, ie the bar is not under the overlay. I cannot use builtin modal or react-native-modal, is there any way with regular views to render over navigation bar?

1 Answers

I ended up displaying the modal view from a root container where it is at the same level as navigation item.

RootContainer.js:

render() {
    return (
        <View style={{ flex: 1 }}>
            <StatusBar barStyle='dark-content'></StatusBar>
            <Navigation />

            {isModalVisible && <View style={styles.overlay}>
                                      ... Modal content
                               </View> } />}
        </View>
    )
}

...
const AppNavigator = createStackNavigator({
    Home: HomeView,
    Detail: DetailView
},

let Navigation = createAppContainer(AppNavigator)

and App renders the RootContainer:

export default class App extends React.Component {
    render() {
        return (
            <Provider store={store}>
                <RootContainer />
            </Provider>
        )
    }
}

This is not the most optimal solution as you are carrying data from a component all the way up to root. But it's one of the known shortcomings of react-navigation. You can see some ideas and discussion here https://github.com/react-navigation/react-navigation/issues/363

For those who use redux use like me: You have to nest one more level (not render screens or the modal from App but RootContainer) because redux doesn't let creating store in App and using connect at the same time. Reference: https://stackoverflow.com/a/41892948/837244

Related