反应导航:动态设置“模式”设置(/标头呈现双倍,后退按钮消失)

时间:2018-07-25 17:40:34

标签: react-native react-navigation

在我的应用中,我有三个屏幕:ScreenAScreenBScreenC。它们都应具有标题,并且都应具有带有上一屏幕名称的后退按钮。我希望ScreenA能够使用模式动画打开ScreenB

const ModalStack = createStackNavigator(
  {
    ScreenA,
    ScreenB
  },
  {
    initialRouteName: "ScreenA",
    mode: "modal"
  }
);

并且ScreenA也应该能够使用默认的滑动动画从右到左打开ScreenC。问题是,StackNavigator已经配置了模式模式。有没有办法动态设置模式?这样就可以使用从ScreenAScreenB的模式,以及从ScreenAScreenC的卡吗?

此外,在这种情况下如何处理标题? (出于我提出这个问题的原因,请进一步阅读。)

这是我阅读文档后尝试过的方法。 It describes a similar scenario.

这是本教程为我翻译的方式:

const SlidingStack = createStackNavigator(
  {
    ScreenA,
    ScreenC
  }
);

const ModalStack = createStackNavigator(
  {
    SlidingStack,
    ScreenB
  },
  {
    mode: "modal"
  }
);

此解决方案的问题是,当我在ScreenA上时,标头现在呈现双倍。此外,当我打开模式ScreenB时,后退按钮为空白。

编辑

在尝试按照文档解决此问题时,我找到了双标头渲染的解决方案:

const SlidingStack = createStackNavigator(
  {
    ScreenA,
    ScreenC
  }
);

const ModalStack = createStackNavigator(
  {
    SlidingStack,
    ScreenB
  },
  {
    mode: "modal",
    navigationOptions: ({ navigation }) => {
      const options = {}
      if (navigation.state.routeName === "SlidingStack") options["header"] = null;
      return options;
    }
  }
);

此解决方案的问题在于,后退按钮仍然没有任何文本。

编辑:

根据我从Pritish中学到的知识,下面是我最终得到的代码:

const IOS_MODAL_ROUTES = ["OptionsScreen"];

let dynamicModalTransition = (
  transitionProps: NavigationTransitionProps,
  prevTransitionProps: NavigationTransitionProps
): TransitionConfig => {
  if (
    IOS_MODAL_ROUTES.some(
      screenName =>
        screenName === transitionProps.scene.route.routeName ||
        (prevTransitionProps && screenName === prevTransitionProps.scene.route.routeName)
    )
  ) {
    return StackViewTransitionConfigs.defaultTransitionConfig(
      transitionProps,
      prevTransitionProps,
      true
    );
  }
  return StackViewTransitionConfigs.defaultTransitionConfig(
    transitionProps,
    prevTransitionProps,
    false
  );
};

它使用React Navigation V2自己的过渡。

1 个答案:

答案 0 :(得分:2)

回到docs

headerBackTitle:默认为上一场景的headerTitle

在您的实现中,您尝试从ScreenA移至ScreenB的标头为空的ScreenA,因此因此后退按钮不包含标题。

在某些情况下(根据您的设计),您通常会从非标题屏幕过渡到标题屏幕,因此该解决方案将不起作用。

一种解决方法是使用default(屏幕过渡)和modal过渡(模式过渡)创建一个Transitioner,并将其设置在{{3 }} StackNavigatorConfig 的选项为

let CustomTransitionConfig = () => {
    return {
        screenInterpolator: (sceneProps) => {
            const { position, scene } = sceneProps;
            const { index, route } = scene;
            const params = route.params || {};
            const transition = params.transition || 'default';
            return {
                modal: ModalTransition(index, position),
                default: ScreenTransition(index, position),
            }[transition];
        }
    }
};

createStackNavigator({
...
   {transitionConfig: CustomTransitionConfig}
...

并在导航时使用过渡参数,如果您想将模态作为

this.props.navigation.navigate({routeName: 'ScreenC', params: {transition: 'modal'}}