我需要在我正在处理的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是否适用于此用例?如果没有,在React Native应用程序中模拟UISplitViewController
的其他方法是什么?
答案 0 :(得分:0)
后退按钮行为不正确的问题是我的错。其中一个屏幕有一个后退按钮处理程序,它始终返回true
,因此消耗所有后退按钮(呃!)。我修复了这个并将以下后退按钮处理程序添加到MasterDetailView
:
private onPressBack = (): boolean => {
const action = NavigationActions.back();
return this.detailNavigator.dispatch(action) || this.masterNavigator.dispatch(action);
};
是的,有一种方法可以确定导航器是否消耗了一个动作:navigator.dispatch(action)
如果事件被消耗则返回true
,否则返回false
。
修复了后退按钮的问题后,此设置可以很好地模拟UISplitViewController
。