react-native-shared-element icon indicating copy to clipboard operation
react-native-shared-element copied to clipboard

Support ModalPresentationIOS transition preset

Open mrousavy opened this issue 4 years ago β€’ 7 comments

The animation begins smoothly, but when the animation finishes, the items (SharedElements) are off by some pixels which causes this stuttering glitch. This issue only appears when using the ModalPresentationIOS transition preset. All other presets work fine.

Demo here: Screen-Recording-2020-03-28-at-19 09 06

My Navigator:

const SharedElementStack = createSharedElementStackNavigator();
function HomeSharedElementStackNavigator() {
  return (
    <SharedElementStack.Navigator
      mode="modal"
      screenOptions={{
        gestureEnabled: false,
        cardOverlayEnabled: true,
        ...TransitionPresets.ModalPresentationIOS,     // <-- The preset causing this issue!
      }}
      headerMode="none">
      <SharedElementStack.Screen
        name="HomeGridScreen"
        component={HomeGridScreen}
      />
      <SharedElementStack.Screen
        name="ItemDetailsScreen"
        component={ItemDetailsScreen}
        sharedElementsConfig={(route, otherRoute, showing) => {
          const {item} = route.params;
          return [
            {
              id: `item.${item.id}.image`,
              animation: 'fade',
            },
            {
              id: `item.${item.id}.title`,
              animation: 'fade',
            },
            {
              id: `item.${item.id}.description`,
              animation: 'fade',
            },
          ];
        }}
      />
    </SharedElementStack.Navigator>
  );
}

I've tried playing around with the animation property, but I can't seem to get it working with this animation I found in the example project (springyFadeIn.js):

import {Animated} from 'react-native';
export function springyFadeIn() {
  const transitionSpec = {
    timing: Animated.spring,
    tension: 10,
    useNativeDriver: true,
  };
  return {
    transitionSpec,
    screenInterpolator: ({position, scene}) => {
      const {index} = scene;

      const opacity = position.interpolate({
        inputRange: [index - 1, index],
        outputRange: [0, 1],
      });

      return {opacity};
    },
  };
}

Packages used:

// ...
    "react": "16.9.0",
    "react-native": "0.61.5",
    "react-navigation-shared-element": "^5.0.0-alpha1",
// ...

I don't know if that's a bug in the library or if I am making a mistake, would appreciate some help here!

mrousavy avatar Mar 28 '20 18:03 mrousavy

I've investigated the issue further and noticed that this bug only appears when using the ModalPresentationIOS or ScaleFromCenterAndroid transition preset in the screenOptions of the Navigator.

<SharedElementStack.Navigator
  mode="modal"
  screenOptions={{
    gestureEnabled: false,
    cardOverlayEnabled: true,
    ...TransitionPresets.ModalPresentationIOS,      // <-- this right here
  }}
  ...

mrousavy avatar Mar 29 '20 12:03 mrousavy

Hi πŸ‘‹This problem appears to be on the native side and is has to do with additional "transforms" applied by the ModalPresentationIOS.

Unfortunately ModalPresentationIOS wont work at the moment.

IjzerenHein avatar Mar 29 '20 17:03 IjzerenHein

I've moved this issue here πŸ‘

IjzerenHein avatar Mar 29 '20 17:03 IjzerenHein

+1

AmnaHijjawi avatar Jan 06 '21 11:01 AmnaHijjawi

+1

evanjmg avatar May 13 '21 16:05 evanjmg

TransitionPresets.ModalSlideFromBottomIOS works better for now as a workaround

evanjmg avatar May 13 '21 16:05 evanjmg

Status update: This preset still doesn't work on both Android and iOS. Some glitches have been resolved with regards to vertical translations, but the top position is still not obtained correctly. As an alternative, please use one of the other presets (nearly all of them work correctly). You can view the supported transitions in the react-navigation example app: https://github.com/IjzerenHein/react-navigation-shared-element/tree/main/example

IjzerenHein avatar Aug 16 '21 15:08 IjzerenHein