Я новичок в react-navigation
и пытаюсь оборачивать голову тем, как сделать следующее:
Учитывая эту навигационную структуру:
RootTabNavigator
LoggedOut_StackNavigator
...
LoggedIn_StackNavigator
LoggedIn_TabNavigator <-- TabBar rendered by this Navigator
TabA_StackNavigator
ScreenA
ScreenB
Я хотел бы иметь возможность перемещаться от ScreenA
до ScreenB
, используя типичный переход "сползать вправо", таким образом, чтобы TabBar
был показан на ScreenA
, но не отображается на ScreenB
. Другими словами, когда я перехожу к ScreenB
, я хочу, чтобы он занял все окно.
Как только пользователь перейдет от ScreenA
до ScreenB
, он может либо нажать кнопку "Назад", чтобы вернуться к ScreenA
, либо перейти к новым маршрутам, используя тот же переход с TabBar
still not.
Что я пробовал:
-
navigationOptions.tabBarVisible
: это свойство работает только при применении к TabA_StackNavigator
, что означает, что все экранов в стеке также скрывают 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",
}
Любая помощь очень ценится!
Ответ 1
По-видимому, navigationOptions
внутреннего компонента влияет также на родительский навигатор навигатора.
Решение
Это означает, что этот код должен работать для вас:
class ScreenB extends React.Component {
static navigationOptions = {
header: () => null, //this will hide the Stack navigator header (TabA_StackNavigator)
tabBarVisible: false //this will hide the TabBar navigator header (LoggedIn_TabNavigator)
}
Описание
Во-первых, вы можете настроить параметры навигации на отдельный экран (компонент). Вы можете увидеть, как в фрагменте кода выше или здесь: React Navigation - Опции экранной навигации
Во-вторых, вы пытались:
Добавление его к экранам внутри StackNavigator не имеет эффекта.
Это не сработало, потому что для скрытия заголовка StackNavigator требуется установить для поля header
значение null
.
Из React Navigation:
React Element или функция, которая задает HeaderProps, возвращает React Элемент, отображаемый в виде заголовка. Настройка для null скрывает заголовок
В-третьих,, используя tabBarVisible, на самом деле правильно, но влияет только на TabNavigator. И чтобы он исчез только для одной вкладки, а не для всех вкладок, вам нужно установить ее на конкретном экране. ScreenB
в вашем случае.
Надеюсь, это поможет!
Ответ 2
Следующее - это то, что в конечном итоге работает для меня, поэтому я отправляю ему надежды на то, что он помогает другим. У меня не было шанса попробовать реализацию @talzaj
, поэтому я оставлю его другим, чтобы поддерживать все, что подходит для них. Следующее решение работает для меня хорошо, в том числе внутри вложенных навигаторов.
Я обновил свою навигационную структуру, чтобы:
-
LoggedIn_StackNavigator
по-прежнему имеет LoggedIn_TabNavigator
как один из его экранов, и этот LoggedIn_TabNavigator
является начальным маршрутом LoggedIn_StackNavigator
, как установлено с помощью initialRouteName
.
-
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;
Оттуда я написал вспомогательную 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>;
}
}