software-mansion / react-native-reanimated

React Native's Animated library reimplemented
https://docs.swmansion.com/react-native-reanimated/
MIT License
9.03k stars 1.3k forks source link

Exiting animation skipped/not visible when unmounting a `FullWindowOverlay` from react-native-screens #5409

Open matthieugicquel opened 11 months ago

matthieugicquel commented 11 months ago

Description

When unmounting a FullWindowOverlay from react-native-screens, exiting animations of children of the FullWindowOverlay aren't displayed. The children disappear immediately.

// See snack for full example
const Broken = () => {
  return (
    <FullWindowOverlay>
      <Animated.View
        entering={FadeIn}
        exiting={FadeOut} // ❌ This animation is not visible when unmounting `<Broken />`
      />
    </FullWindowOverlay>
  );
};

I started debugging the issue and I can tell that:

Steps to reproduce

Press the toggle button in the linked snack

Note: I know there are other issues linked to exiting animations that may or may not have the same root cause as this one, but I thought it would be useful to have a clean issue with a minimal reproduction

Snack or a link to a repository

https://snack.expo.dev/@matthieugc/reanimated-exiting-issue?platform=ios

Reanimated version

3.3.0

React Native version

0.72.6

Platforms

iOS

JavaScript runtime

Hermes

Workflow

Expo Dev Client or Expo Go

Architecture

Paper (Old Architecture)

Build type

Both

Device

None

Device model

Issue visible on simulators and real devices

Acknowledgements

Yes

TowhidKashem commented 10 months ago

Encountering the same issue, I am displaying a toast component inside the FullWindowOverlay, it uses a fade in and fade out animation on enter/exit and works as expected without the FullWindowOverlay. But when wrapped in the FullWindowOverlay, I only see the fade in enter animation, on exist it just disappears suddenly without Fading out..

rrasconc commented 8 months ago

If you extract the FullWindowOverlay outside of the conditional rendering, it seems to work fine.

https://snack.expo.dev/@innoval/reanimated-exiting-issue

export default function App() {
  const [isVisible, setIsVisible] = useState(false);

  return (
    <View style={styles.container}>
      <Button onPress={() => setIsVisible(!isVisible)} title="Toggle" />
        <FullWindowOverlay>
          {isVisible && <MyExitingIsBroken />}
        </FullWindowOverlay>
    </View>
  );
}

const MyExitingIsBroken = () => {
  return (
      <Animated.View
        style={styles.square}
        entering={FadeIn.duration(1000)}
        exiting={FadeOut.duration(1000)}
      /> 
  );
};
matthieugicquel commented 1 month ago

If you extract the FullWindowOverlay outside of the conditional rendering, it seems to work fine.

It fixes the animation for sure.

But if you don't conditionally render the FullWindowOverlay, the VoiceOver accessibility of your app (and your E2E tests if you have any) will be completely broken, nothing outside of the overlay will be accessible.

This is the case since this PR on react-native-screens was merged