Мне нужно реализовать поддержку планшетов в приложении React Native, над которым я работаю. Мы решили, что использование UISplitViewController
имеет для нас наибольшее значение, но React Navigation (https://reactnavigation.org) не поддерживает его.
Я попытался решить эту проблему простым способом, поместив 2 навигатора рядом друг с другом и изменив их getStateForAction
, чтобы открыть определенные экраны в подробном представлении:
export interface Props {
MasterNavigator: NavigationContainer;
DetailNavigator: NavigationContainer;
detailRouteNames: string[];
}
export class MasterDetailView extends React.Component<Props> {
masterNavigator: any;
detailNavigator: any;
componentDidMount() {
const { MasterNavigator, DetailNavigator, detailRouteNames } = this.props;
const defaultMasterGetStateForAction = MasterNavigator.router.getStateForAction;
MasterNavigator.router.getStateForAction = (action: any, state: any) => {
if (action.type === NavigationActions.NAVIGATE && detailRouteNames.indexOf(action.routeName) !== -1) {
action.params.isRootScreen = true;
this.detailNavigator.dispatch(NavigationActions.reset({ index: 0, actions: [action] }));
return state;
}
return defaultMasterGetStateForAction(action, state);
};
const defaultDetailGetStateForAction = DetailNavigator.router.getStateForAction;
DetailNavigator.router.getStateForAction = (action: any, state: any) => {
if (action.type === NavigationActions.BACK && state.routes.length === 1) {
this.masterNavigator.dispatch(NavigationActions.back());
return null;
}
return defaultDetailGetStateForAction(action, state);
};
}
render() {
const { MasterNavigator, DetailNavigator } = this.props;
return (
<View style={styles.view}>
<View style={styles.masterContainer}>
<MasterNavigator ref={(mn: any) => this.masterNavigator = mn}/>
</View>
<View style={styles.divider}/>
<View style={styles.detailContainer}>
<DetailNavigator ref={(dn: any) => this.detailNavigator = dn}/>
</View>
</View>
);
}
}
Главный навигатор - это TabNavigator
с StackNavigator
с на каждой вкладке, подробный навигатор - StackNavigator
. Вот как это выглядит:
Этот подход вроде работает, но кнопка возврата на Android ведет себя некорректно. Я хочу, чтобы он возвращался назад в подробном навигаторе, затем в главном навигаторе. Можно заставить его работать с парой хаков, но тогда становится невозможным вернуться назад из приложения с помощью кнопки назад (по какой-то причине, когда я нажимаю на нее, ничего не происходит). Я мог бы попытаться исправить это, переопределив поведение кнопки «Назад» и отправив действие «Назад» на навигаторы мастер / подробности или закрыв приложение, но при отправке действия на навигатор невозможно узнать, ответило ли оно на него или нет ( особенно с главным навигатором, который является TabNavigator
), поэтому кажется, что я застрял.
Есть ли какие-то особые соображения при использовании навигаторов таким образом? Подходит ли React Navigation для этого варианта использования? Если нет, то каковы другие способы эмуляции UISplitViewController
в приложениях React Native?