我如何使用 React Navigation 使 TabNavigator 按钮推送模态屏幕

How do i make a TabNavigator button push a modal screen with React Navigation

使用 React Navigation 选项卡导航器 https://reactnavigation.org/docs/navigators/tab 如何使其中一个选项卡按钮将屏幕向上推为全屏模式?我看到堆栈导航器有一个 mode=modal 选项。单击 TakePhoto 选项卡按钮时如何使用该模式?目前点击它仍然显示底部的标签栏。

const MyApp = TabNavigator({
  Home: {
    screen: MyHomeScreen,
  },
  TakePhoto: {
    screen: PhotoPickerScreen, // how can I have this screen show up as a full screen modal?
  },
});

使标签栏消失的一种方法是使用 visible: false:

隐藏标签栏
const MyApp = TabNavigator({
  Home: {
    screen: MyHomeScreen,
  },
  TakePhoto: {
    screen: PhotoPickerScreen,
    navigationOptions: {
      tabBar: {
        visible: false,
      },
    },
  },
});

但是,这似乎并没有触发任何到全屏的转换,我想这是需要的?

另一种选择是将 PhotoPickerScreen 包装在一个新的 StackNavigator 中,并将该导航器设置为模式 ='modal'。

您可能必须以某种方式触发从 tabItem 上的 onPress 到该模式的导航(例如 navigation.navigate('TakePhoto')。)

请注意,我正在努力思考如何最好地自己构建导航,所以……

第三个选项,将 StackNavigator 实现为父级,然后将 MyApp TabNavigator 添加为其中的第一个路由,可能是最灵活的解决方案。然后 TakePhoto 屏幕将与 TabNavigator 处于同一级别,允许您从任何地方路由到它。

有兴趣听听你的想法!

实际上,react-navigation to change the way of presentation on the fly from default to modal (see the discussion about this here) 中没有任何支持。我 运行 遇到了同样的问题,并通过使用最上面的 StackNavigatorheaderMode 设置为 none 并将 mode 设置为 modal 解决了这个问题:

const MainTabNavigator = TabNavigator(
    {
        Tab1Home: { screen: Tab1Screen },
        Tab2Home: { screen: Tab2Screen }
    }
);

const LoginRegisterStackNavigator = StackNavigator({
    Login: { screen: LoginScreen }
});

const ModalStackNavigator = StackNavigator({
    MainTabNavigator:          { screen: MainTabNavigator            },
    LoginScreenStackNavigator: { screen: LoginRegisterStackNavigator }
}, {
    headerMode: 'none',
    mode:       'modal'
});

这允许我在 Tab1ScreenTab2Screen 中执行以下操作(使用 redux)以从我想要的任何地方调出模态视图:

this.props.navigation.navigate('LoginScreenStackNavigator');

文档在某些方面是不完整的,但这里是:

    export default class HomeScene extends Component {

        static navigationOptions = {
        title: 'foo',
        header:{
                    visible: true
                }
        }
        ....
      }

不确定这是否仍然与您相关,但我设法找到了实现它的方法。

所以我设法通过使用 tabNavigatorConifg 中的 tabBarComponent 使其工作,您可以根据索引停止选项卡导航。

   tabBarComponent: ({jumpToIndex, ...props, navigation}) => (
        <TabBarBottom
            {...props}
            jumpToIndex={index => {
                if (index === 2) {
                    navigation.navigate('camera')
                }
                else {
                    jumpToIndex(index)
                }
            }}
        />

    )

完成此操作后,我在选项卡视图顶部模态显示视图的方法是将 tabnavigator 放在 stacknavigatior 内,然后导航到 stacknavigator 内的新屏幕。

react-navigation 的 bottomTabNavigator 有一个 tabBarOnPress 导航选项,您可以使用它来覆盖 Tab 键:

https://reactnavigation.org/docs/en/bottom-tab-navigator.html#tabbaronpress

const AppContainer = createStackNavigator(
  {
    default: createBottomTabNavigator(
      {
        TAB_0: Stack0,
        TAB_1: Stack1,
        TAB_2: Stack2,
        TAB_3: View // plain rn-view, or any old unused screen
      },
      {
        defaultNavigationOptions: {
          // other tab navigation options...
          tabBarOnPress: ({ navigation, defaultHandler }) => {
            if (navigation.state.key === 'TAB_3') {
              navigation.navigate('tabToOpenAsModal');
            } else {
              defaultHandler();
            }
          }
        }
      }
    ),
    tabToOpenAsModal: {
      screen: TabToOpenAsModalScreen
    }
  },
  {
    mode: 'modal',
    headerMode: 'none'
  }
);

如果您将选项卡导航器嵌套在带有模式的堆栈导航器中,则可以在按下选项卡栏按钮时打开它。由于模式是打开的而不是选项卡,当模式关闭时,应用程序 returns 显示在按下模式选项卡之前可见的屏幕上。

我建议两种解决方案

第一个是关于隐藏它

第二个请阅读:https://reactnavigation.org/docs/hiding-tabbar-in-screens

<Tab.Screen
name={Routes.CREATE_ANNOUNCEMENT_SCREEN}
// name={Routes.TEST_SCREEN}
options={{
.
.
.
  tabBarVisible: false,    <----- solution 1
  tabBarButton: (props) => (   <----- or solution 2
    <TouchableOpacity
      {...props}
      onPress={() => {
        navigation.navigate(Routes.DETAILS_SCREEN);
      }}
    />
  ),
}}
component={CreateAnnouncementScreen}
/>