使用 React Navigation 实现 UISplitViewController

And*_*nko 5 react-native react-navigation

我需要在我正在开发的 React Native 应用程序中实现平板电脑支持。我们认为 withUISplitViewController对我们来说最有意义,但是 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>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

主导航器是一个在每个选项卡中TabNavigator带有StackNavigators 的导航器,详细导航器是一个StackNavigator. 这是它的外观: 结果

这种方法有效,但 Android 上的后退按钮行为不正确。我希望它在详细信息导航器中导航回来,然后在主导航器中导航。可以通过一些 hack 使其工作,但是使用后退按钮从应用程序返回变得不可能(出于某种原因,当我单击它时没有任何反应)。我可以尝试通过覆盖后退按钮的行为并将返回操作分派给主/详细信息导航器或关闭应用程序来解决此问题,但是当将操作分派给导航器时,无法知道它是否响应了它(特别是主导航器,它是一个TabNavigator),所以看起来我被卡住了。

以这种方式使用导航器时是否有一些特殊注意事项?React Navigation 甚至适合这个用例吗?如果没有,UISplitViewController在 React Native 应用程序中模拟的其他方法是什么?

And*_*nko 4

后退按钮行为不正确的问题是我的错。其中一个屏幕有一个后退按钮处理程序,它总是返回true,因此消耗了所有后退按钮按下的时间(废话!)。我解决了这个问题,并将以下后退按钮处理程序添加到MasterDetailView

private onPressBack = (): boolean => {
    const action = NavigationActions.back();
    return this.detailNavigator.dispatch(action) || this.masterNavigator.dispatch(action);
};
Run Code Online (Sandbox Code Playgroud)

是的,有一种方法可以查明导航器是否消耗了某个操作:如果事件被消耗,则navigator.dispatch(action)返回,否则返回。truefalse

一旦后退按钮的问题得到解决,这个设置就可以UISplitViewController很好地模拟。