从嵌套的 StackNavigator 中隐藏 TabBar 的反应导航屏幕

react-navigation Screen that conceals TabBar from nested StackNavigator

我是 react-navigation 的新手,正在努力思考如何执行以下操作:

鉴于此导航结构:

RootTabNavigator 

  LoggedOut_StackNavigator

    ...

  LoggedIn_StackNavigator

    LoggedIn_TabNavigator <-- TabBar rendered by this Navigator

      TabA_StackNavigator

        ScreenA
        ScreenB

我希望能够使用典型的 "slide in from right" 转换从 ScreenA 导航到 ScreenB,这样 TabBar ScreenA 上可见,但 ScreenB 上不可见。换句话说,当我导航到 ScreenB 时,我希望它占据整个 window。

一旦用户从 ScreenA 转换到 ScreenB,他们可以按后退按钮 return 返回到 ScreenA,或者使用与 TabBar 相同的过渡仍然 可见。

我试过的:

非常感谢任何帮助!

编辑:此答案与 react-nagivation v1.~(v2.0 之前)相关

按照评论中的建议,看到这个问题:

https://github.com/react-navigation/react-navigation-tabs/issues/19


Apparently,内部组件的 navigationOptions 也会影响包含导航器的 parent 导航器。

解决方案

这意味着此代码应该适合您:

class ScreenB extends React.Component {
  static navigationOptions = {
    header: () => null,  //this will hide the Stack navigator's header (TabA_StackNavigator)
    tabBarVisible: false //this will hide the TabBar navigator's header (LoggedIn_TabNavigator)
  }

说明

首先, 您可以为每个单独的屏幕(组件)设置导航选项。你可以在上面或这里的代码片段中看到如何:React Navigation - Screen Navigation Options

其次,你试过:

Adding it to the screens inside the StackNavigator has no effect.

它不起作用,因为隐藏 StackNavigator 的 header 需要将 header 字段设置为 null

来自React Navigation documentation:

React Element or a function that given HeaderProps returns a React Element, to display as a header. Setting to null hides header

第三,使用tabBarVisible其实是正确的,但它只影响TabNavigator。并使其仅对一个选项卡而不对所有选项卡消失,您需要在特定屏幕上进行设置。 ScreenB 你的情况。

希望对您有所帮助!

以下是最终对我有用的东西,所以我发布它是希望它能帮助其他人。我还没有机会尝试 @talzaj 的实现,所以我会把它留给其他人,让他们投票选出最适合他们的东西。以下解决方案对我来说效果很好,包括嵌套导航器内部。

我更新了我的导航结构:

  1. LoggedIn_StackNavigator 仍然有 LoggedIn_TabNavigator 作为它的屏幕之一,而这个 LoggedIn_TabNavigator 是使用 initialRouteName 设置的 LoggedIn_StackNavigator 的初始路线。
  2. LoggedIn_StackNavigator 还包含 需要全屏显示并隐藏标签栏的每个屏幕的路由 。 (如果您正在重复使用屏幕,其中一些显示的标签栏可见而另一些则不可见,确保对重复使用同一屏幕的路由使用唯一键 .

导航结构

因此,导航结构如下所示:

RootTabNavigator 

  LoggedOut_StackNavigator

  LoggedIn_StackNavigator

    ScreenA // ( reuse screen component, different route key )

    ScreenB // ( reuse screen component, different route key )

    LoggedIn_TabNavigator <-- TabBar rendered by this Navigator

      TabA_StackNavigator

        ScreenA
        ScreenB

LoggedIn_StackNavigator:

LoggedIn_StackNavigator 看起来像:

import { StackNavigator } from 'react-navigation';
import LoggedIn_TabNavigator from './LoggedIn_TabNavigator';
import { 
  ScreenA, 
  ScreenB, 
} from './LoggedIn_TabNavigator/TabA_StackNavigator/Screens';

const LoggedIn_StackNavigator = StackNavigator({
  WithoutTabBar_ScreenA: {
     screen: ScreenA
  },
  WithoutTabBar_ScreenB: {
    screen: ScreenB
  },
  LoggedIn_TabNavigator: {
    screen: LoggedIn_TabNavigator
  }
}, {
  initialRouteName: 'LoggedIn_TabNavigator'
});

export default LoggedIn_StackNavigator;

从那里,我写了一个 helper HOC 来推送全屏路由:

import React from 'react';
import { withNavigation } from 'react-navigation';
import { fullScreenRoutePrefix } from './somewhere';

export default function withNavigateFullScreen(Child) {

  @withNavigation
  class WithNavigateFullScreenHOC extends React.Component {

    navigateToFullScreenRoute = (routeName, params) => {          
      this.props.navigation.navigate(
        `${fullScreenRoutePrefix}${routeName}`, params
      );
    }

    render() {
      return (
        <Child 
          {...this.props} 
          navigateFullScreen={this.navigateToFullScreenRoute} 
        />
      );
    }
  }
  return WithNavigateFullScreenHOC;
}

然后我可以像这样导航到全屏路线:

import React from 'react';
import { withNavigateFullScreen } from 'components/higher-order';
import { Text } from 'react-native';

@withNavigateFullScreen
export default class ScreenA extends React.Component {
  goToScreenB = () => {
    this.props.navigateFullScreen('ScreenB');
  }
  render() {
    return <Text onPress={this.goToScreenB}>Go To Screen B</Text>;
  }
}