从嵌套的 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
相同的过渡仍然 不 可见。
我试过的:
navigationOptions.tabBarVisible
:这个 属性 似乎只适用于 TabA_StackNavigator
本身,这意味着 all其堆栈中的屏幕也隐藏了 TabBar
。将其添加到 StackNavigator 内的屏幕没有任何效果。
添加新的 AllScreens_StackNavigator
作为 LoggedIn_TabNavigator
的同级并导航到此导航器内的路线,我收到错误:Expect nav state to have routes and index, {"routeName":"ScreenB", "params": {}, "key": "init-id-1516..."}
。我派遣的导航操作试图做到这一点:
{
"action": Object {
"params": Object {},
"routeName": "ScreenB",
"type": "Navigation/NAVIGATE",
},
"params": Object {},
"routeName": "AllScreens_StackNavigator",
"type": "Navigation/NAVIGATE",
}
非常感谢任何帮助!
编辑:此答案与 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
的实现,所以我会把它留给其他人,让他们投票选出最适合他们的东西。以下解决方案对我来说效果很好,包括嵌套导航器内部。
我更新了我的导航结构:
LoggedIn_StackNavigator
仍然有 LoggedIn_TabNavigator
作为它的屏幕之一,而这个 LoggedIn_TabNavigator
是使用 initialRouteName
设置的 LoggedIn_StackNavigator
的初始路线。
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>;
}
}
我是 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
相同的过渡仍然 不 可见。
我试过的:
navigationOptions.tabBarVisible
:这个 属性 似乎只适用于TabA_StackNavigator
本身,这意味着 all其堆栈中的屏幕也隐藏了TabBar
。将其添加到 StackNavigator 内的屏幕没有任何效果。添加新的
AllScreens_StackNavigator
作为LoggedIn_TabNavigator
的同级并导航到此导航器内的路线,我收到错误:Expect nav state to have routes and index, {"routeName":"ScreenB", "params": {}, "key": "init-id-1516..."}
。我派遣的导航操作试图做到这一点:{ "action": Object { "params": Object {}, "routeName": "ScreenB", "type": "Navigation/NAVIGATE", }, "params": Object {}, "routeName": "AllScreens_StackNavigator", "type": "Navigation/NAVIGATE", }
非常感谢任何帮助!
编辑:此答案与 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
的实现,所以我会把它留给其他人,让他们投票选出最适合他们的东西。以下解决方案对我来说效果很好,包括嵌套导航器内部。
我更新了我的导航结构:
LoggedIn_StackNavigator
仍然有LoggedIn_TabNavigator
作为它的屏幕之一,而这个LoggedIn_TabNavigator
是使用initialRouteName
设置的LoggedIn_StackNavigator
的初始路线。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>;
}
}