Kamil Kamili
Kamil Kamili

Reputation: 1927

Disable Swipe of Parent TabNavigator when in certain Screens in Nested Navigators

I have been trying to implement nested Navigators for my app. The Structure of the app is quite simple.

RootNavigation(TabNavigator):
    - Camera
    - HomeNavigation (TabNavigator)
    - MessagesList

So the app starts on the HomeNavigation on display by default. Swipe Left for Camera and swipe Right to MessagesList.

Now the HomeNavigation is further divided like this:

HomeNavigation (TabNavigator):
    - News Feed List
    - NotificationsList
    - Search News

In this Navigator, News Feed List is shown by default. Now when I go to NotificationsList or Search News in Home Navigation. Swiping Left or Right takes me to Camera and MessagesList which I don't want. I only want this feature when I am in News Feed List. Now I was reading the docs but couldn't quite understand how to disable swiping in the RootNavigation (Parent Navigator) from inside the child. Also later in the development stage the News Feed List will be converted to a StackNavigator where a user can select each news item and read it in full detail. I would also want it to be disabled when going deeper in the NewsFeedList.

Maybe this code will help better understand my situation:

HomeNavigationConfigurtation:

const homeNavigationConfiguration = {
    TabOneNavigation: {
        screen: FeedScreen,
        navigationOptions: {
            tabBarLabel: 'Home',
            tabBarIcon: ({ tintColor, focused }) => {
                return (
                    <Ionicons
                        name={focused ? 'ios-home' : 'ios-home-outline'}
                        size={30}
                        style={{ color: tintColor }}
                    />
                );
            }
        }
    },
    TabTwoNavigation: {
        screen: SearchTab,
        navigationOptions: {
            tabBarLabel: 'Search',
            tabBarIcon: ({ tintColor, focused }) => {
                return (
                    <Ionicons
                        name={focused ? 'ios-search' : 'ios-search-outline'}
                        size={30}
                        style={{ color: tintColor }}
                    />
                );
            }
        }
    },
    TabThreeNavigation: {
        screen: NotificationTab,
        navigationOptions: {
            tabBarLabel: 'Notify',
            tabBarIcon: ({ tintColor, focused }) => {
                return (
                    <Ionicons
                        name={focused ? 'ios-list' : 'ios-list-outline'}
                        size={30}
                        style={{ color: tintColor }}
                    />
                );
            }
        }
    }
};

const tabBarConfiguration = {
    //...other configs
    tabBarComponent: TabBarBottom,
    tabBarPosition: 'bottom',
    swipeEnabled: false,
    animationEnabled: false,
    lazy: true,
    tabBarOptions: {
        showIcon: true,
        showLabel: false,
        activeTintColor: '#347FC4',
        inactiveTintColor: '#929AA1',
        activeBackgroundColor: '#FFF',
        inactiveBackgroundColor: '#FFF'
    }
};

export const HomeNavConfiguration = TabNavigator(routeConfiguration, tabBarConfiguration);

HomeNavigation:

class HomeNavigationextends Component {
    render() {
        const { dispatch, navigationState } = this.props;
        return (
            <HomeNavigationConfiguration
                navigation={
                    addNavigationHelpers({
                        dispatch,
                        state: navigationState,
                    })
                }
            />
        );
    }
}

const mapStateToProps = (state) => {
    return {
        navigationState: state.homeNavState,
    };
};

export default connect(mapStateToProps)(HomeNavigation);

HomeNavigationReducer:

export default (state, action) => {
    if (action.type === 'JUMP_TO_TAB') {
        return { ...state, index: 0 };
    }
    return HomeNAvigationConfig.router.getStateForAction(action, state);
};

RootNavigationConfiguration:

const routeConfiguration = {
    RootNavigationScreenLeft: {
        screen: CameraScreen,
        navigationOptions: {
            tabBarVisible: false
        }
    },
    RootNavigationScreenMiddle: {
        screen: RootTab,
        navigationOptions: {
            tabBarVisible: false
        }
    },
    RootNavigationScreenRight: {
        screen: MessagesListScreen,
        navigationOptions: {
            tabBarVisible: false
        }
    }
};

const tabBarConfiguration = {
    //...other configs
    swipeEnabled: true,
    animationEnabled: true,
    lazy: true,
    initialRouteName: 'RootNavigationScreenMiddle'
};

export const RootNavigationConfig = TabNavigator(routeConfiguration, tabBarConfiguration);

Root Navigation

class RootNavigationextends React.Component {
    render() {
        const { dispatch, navigationState } = this.props;
        return (
            <RootNavigationConfig
                navigation={
                    addNavigationHelpers({
                        dispatch,
                        state: navigationState,
                    })
                }
            />
        );
    }
}

const mapStateToProps = (state) => {
    return {
        navigationState: state.rootNavState,
    };
};

export default connect(mapStateToProps)(RootNavigation);

Any solutions or advice will be highly appreciated. :)

Upvotes: 3

Views: 810

Answers (1)

rodiwa
rodiwa

Reputation: 1770

From a UX perspective, the user might be confused. What you're basically doing is,

RootNavigation (TabNavigator)
- Camera
- News Feed List
- NotificationsList
- Search News
- MessagesList

Consider if this works in your case?

RootNavigation(StackNavigator):
    - Camera
    - HomeNavigation (TabNavigator)
    - MessagesList

HomeNavigation (TabNavigator):
    - News Feed List
    - NotificationsList
    - Search News

As for your question,

I only want this feature when I am in News Feed List

When you setup your navigation, it takes the form TabNavigator(RouteConfigs, TabNavigatorConfig)

You can pass navigationOptions to both, the RouteConfigs and the TabNavigatorConfig. The navigationOptions that you specify in each screen object allows to override the navigationOptions in TabNavigatorConfig. Basically, you pass 'general' configuration for all screens to TabNavigatorConfig navigationOptions and screen-specific to RouteConfigs navigationOptions.

Upvotes: 1

Related Questions