【问题标题】:How do i make a TabNavigator button push a modal screen with React Navigation如何使用 React Navigation 使 TabNavigator 按钮推送模态屏幕
【发布时间】:2021-08-31 15:14:14
【问题描述】:

使用 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?
  },
});

【问题讨论】:

标签: react-native react-navigation


【解决方案1】:

实际上,react-navigation 不支持将演示方式从default 更改为modal(请参阅有关此here 的讨论)。我遇到了同样的问题并通过使用非常顶级的StackNavigatorheaderMode 设置为nonemode 设置为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');

【讨论】:

  • 你能从标签按钮内部调用 this.props 吗?怎么样?
  • @IamLasse 您的意思是来自选项卡内的屏幕还是选项卡按钮本身? “不幸的是”我使用的是 redux,所以我想我有不同的情况:-)
  • 我也用redux。但是我无法调度事件来打开弹出模式或从导航配置所在的主导航器堆栈中调用道具。
  • 谢谢@ThomasKekeisen 这对我很有效!需要注意的一点:如果您希望导航标题出现在 LoginScreenStackNavigator 中,则需要在其选项中将其 headerMode 设置为 screen 否则它将从其外部嵌套导航继承 none 值。
  • 我喜欢这个解决方案
【解决方案2】:

不确定这是否仍然与您相关,但我已经设法实现这一目标。

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

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

    )

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

【讨论】:

  • 我不明白这部分“一旦你完成了这个,我在选项卡视图顶部模态显示视图的方法是将选项卡导航器放在堆栈导航器中,然后导航到一个新的堆栈导航器内的屏幕。”你不会把堆栈导航器放在选项卡里面而不是外面吗?
  • 感谢 ThomasTomTom,这两种解决方案的结合对我来说就像是一种魅力(即使没有 Redux)。
【解决方案3】:

react-navigation 的底部TabNavigator 有一个tabBarOnPress 导航选项,您可以使用它来覆盖标签按下:

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'
  }
);

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

【讨论】:

    【解决方案4】:

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

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

    但是,这似乎不会触发任何到全屏的转换,我猜这是需要的?

    另一个选项可能是将PhotoPickerScreen 包装在新的 StackNavigator 中,并将该导航器设置为 mode='modal'。

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

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

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

    很想听听你的想法!

    【讨论】:

    • 是的,我自己仍然遇到问题 - 您是否找到了在选项卡项本身上设置 onPress 事件的方法?我没有看到任何拦截该选项卡按钮按下的方法。
    【解决方案5】:

    我建议两种解决方案

    第一个是关于隐藏它

    第二个人请阅读: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}
    />
    

    【讨论】:

      【解决方案6】:

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

          export default class HomeScene extends Component {
      
              static navigationOptions = {
              title: 'foo',
              header:{
                          visible: true
                      }
              }
              ....
            }
      

      【讨论】:

      • 看起来我为这个答案粘贴了完全错误的代码。我的错。一定是想在别处回答一个不同的问题
      猜你喜欢
      • 1970-01-01
      • 2019-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-28
      • 1970-01-01
      • 2020-04-20
      相关资源
      最近更新 更多