React native 反应导航:对场景应用单独的变换

React native 反应导航:对场景应用单独的变换,react-native,react-navigation,React Native,React Navigation,对于我的React Native(iOS)应用程序,我想在React Navigation中对StackNavigator中的场景应用不同的过渡 我可能希望NewChild从下到上加载,就像一个模态。或者我想让它从右向左滑动。如果可以定制,那就太好了。从文档中可以看出,对于整个过程,您似乎只能将StackNavigation设置为card或modal。正如您在文档中已经看到的,现在不可能。您可以跟踪并请求此功能。它已经上市,但由于v1尚未发布,您最好的选择可能是: 实现您自己的,以某种方式处理每

对于我的React Native(iOS)应用程序,我想在React Navigation中对StackNavigator中的场景应用不同的过渡


我可能希望NewChild从下到上加载,就像一个模态。或者我想让它从右向左滑动。如果可以定制,那就太好了。从文档中可以看出,对于整个过程,您似乎只能将StackNavigation设置为card或modal。

正如您在文档中已经看到的,现在不可能。您可以跟踪并请求此功能。它已经上市,但由于v1尚未发布,您最好的选择可能是:

  • 实现您自己的,以某种方式处理每个屏幕。我不确定这是否可行
  • 叉一个工具的想法使用的东西。或者简单地将您的fork特定于您的代码,并对其进行维护,直到问题得到解决

  • 多亏了线程中的每个人,它对我起了作用

    我有许多场景只由一个StackNavigator管理,我想为其中一些场景制作不同的动画

    首先,我在我的路由器中设置了一个常量,其中包含了我想通过水平过渡显示的每个场景:

    const horizontalTransitionScenes = [
      AddContact,
    ];
    
    之后,我用StackNavigator设计了我的应用路由器:

    const App = StackNavigator({
      AddContact: {
        screen: AddContact,
      },
      EditContact: {
        screen: EditContact,
      },
    });
    
    我使用了CardStackStyleInterpolator来修改场景之间的过渡。我可以这样导入:
    import CardStackStyleInterpolator from'react navigation/src/views/CardStack/CardStackStyleInterpolator'

    现在,我们可以向StackNavigator添加transitionConfig参数,以根据场景显示不同的动画:

     const App = StackNavigator(
    {
        AddContact: {
            screen: AddContact
        },
        EditContact: {
            screen: EditContact
        }
    },
    {
        transitionConfig: (currentState: any) => {
            if (
                currentState.scenes[
                    currentState.scenes.length - 1
                ].route.routeName.includes(horizontalTransitionScenes)
            ) {
                return {
                    screenInterpolator: CardStackStyleInterpolator.forHorizontal
                };
            }
            return {
                screenInterpolator: CardStackStyleInterpolator.forVertical
            };
        }
    }
    );
    
    使用StackNavigator实现,您将能够为所需场景显示不同类型的动画


    祝您有愉快的一天我可以通过执行一些条件逻辑来完成这项任务,我们现在使用
    react导航
    3.3.2

    您必须从
    react native
    导入
    Easing
    Animated
    ,然后您可以按名称或索引(以下按名称)有条件地渲染特定屏幕的过渡

    通过在导航器外部声明配置,并使用
    {}
    切换
    transitionSpec
    ,它将仅在该特定屏幕上触发——与
    屏幕插值器的条件相同

    Screen1
    Screen2
    有动画,但其他屏幕都没有动画

    const screen2Config = {
      duration: 300,
      easing: Easing.out(Easing.poly(4)),
      timing: Animated.timing,
    };
    
    export const ScreenStack = createStackNavigator({
      Screen1: {
        screen: Screen1,
        navigationOptions: ({ navigation }) => ({
          headerTitle: 'Screen1',
          headerTitleAllowFontScaling: false,
        }),
      },
      Screen2: {
        screen: Screen2,
        navigationOptions: ({ navigation }) => ({
          headerTitle: 'Screen2',
          headerTitleAllowFontScaling: false,
          tabBarVisible: false,
        }),
      },
      Screen3: {
        screen: Screen3,
        navigationOptions: ({ navigation }) => ({
          headerTitle: 'Screen3',
          headerTitleAllowFontScaling: false,
        }),
      },
      Screen4: {
        screen: Screen4,
        navigationOptions: ({ navigation }) => ({
          headerTitle: 'Screen4',
          headerTitleAllowFontScaling: false,
        }),
      },
    }, {
      headerMode: 'float',
      mode: 'modal',
      transitionConfig: sceneProps => ({
        transitionSpec: sceneProps.scene.route.routeName === 'Screen2' ? screen2Config : {},
        screenInterpolator: (sceneProps) => {
          if (sceneProps.scene.route.routeName === 'Screen2') {
            const { layout, position, scene } = sceneProps;
            const { index } = scene;
    
            const width = layout.initWidth;
            const translateX = position.interpolate({
              inputRange: [index - 1, index, index + 1],
              outputRange: [width, 0, 0],
            });
    
            const opacity = position.interpolate({
              inputRange: [index - 1, index - 0.99, index],
              outputRange: [0, 1, 1],
            });
    
            return { opacity, transform: [{ translateX }] };
          }
        },
      }),
    });
    

    您可以使用自定义转换程序执行任何您想要的转换。有一些关于如何做到这一点的好文章。我将尝试将它们链接起来。这个问题还定义了一种可以用来为导航器中的每个屏幕实现不同配置的方法。太棒了,谢谢你的链接!知道了。谢谢你的回复,迈克尔。
    const screen2Config = {
      duration: 300,
      easing: Easing.out(Easing.poly(4)),
      timing: Animated.timing,
    };
    
    export const ScreenStack = createStackNavigator({
      Screen1: {
        screen: Screen1,
        navigationOptions: ({ navigation }) => ({
          headerTitle: 'Screen1',
          headerTitleAllowFontScaling: false,
        }),
      },
      Screen2: {
        screen: Screen2,
        navigationOptions: ({ navigation }) => ({
          headerTitle: 'Screen2',
          headerTitleAllowFontScaling: false,
          tabBarVisible: false,
        }),
      },
      Screen3: {
        screen: Screen3,
        navigationOptions: ({ navigation }) => ({
          headerTitle: 'Screen3',
          headerTitleAllowFontScaling: false,
        }),
      },
      Screen4: {
        screen: Screen4,
        navigationOptions: ({ navigation }) => ({
          headerTitle: 'Screen4',
          headerTitleAllowFontScaling: false,
        }),
      },
    }, {
      headerMode: 'float',
      mode: 'modal',
      transitionConfig: sceneProps => ({
        transitionSpec: sceneProps.scene.route.routeName === 'Screen2' ? screen2Config : {},
        screenInterpolator: (sceneProps) => {
          if (sceneProps.scene.route.routeName === 'Screen2') {
            const { layout, position, scene } = sceneProps;
            const { index } = scene;
    
            const width = layout.initWidth;
            const translateX = position.interpolate({
              inputRange: [index - 1, index, index + 1],
              outputRange: [width, 0, 0],
            });
    
            const opacity = position.interpolate({
              inputRange: [index - 1, index - 0.99, index],
              outputRange: [0, 1, 1],
            });
    
            return { opacity, transform: [{ translateX }] };
          }
        },
      }),
    });