From a40d12c1913a7abdb8df82751666deaecc0f19c5 Mon Sep 17 00:00:00 2001 From: Juliusz Wajgelt <49338439+jwajgelt@users.noreply.github.com> Date: Wed, 14 Dec 2022 11:21:03 +0100 Subject: [PATCH] [Layout Animations][iOS] Fix registering exiting view ancestors (#3849) ## Summary #3824 introduces a bug with how we register ancestors of views with `exiting` animations. When a tree with `exiting` views is reattached to the native view hierarchy, we don't register the ancestors of that tree as ancestors of exiting subviews. This may cause issues with deleting these views early, while there're still `exiting` animations running inside them. ## Test plan --- Example/src/App.tsx | 5 ++ .../DeleteAncestorOfExiting.tsx | 54 +++++++++++++++++++ Example/src/LayoutReanimation/index.ts | 1 + ios/LayoutReanimation/REAAnimationsManager.m | 13 ++++- 4 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 Example/src/LayoutReanimation/DeleteAncestorOfExiting.tsx diff --git a/Example/src/App.tsx b/Example/src/App.tsx index 6769ab9a08d..a7215442d53 100644 --- a/Example/src/App.tsx +++ b/Example/src/App.tsx @@ -30,6 +30,7 @@ import { BasicNestedLayoutAnimation, BasicNestedAnimation, BasicLayoutAnimation, + DeleteAncestorOfExiting, } from './LayoutReanimation'; import AnimatedStyleUpdateExample from './AnimatedStyleUpdateExample'; @@ -69,6 +70,10 @@ if (Platform.OS === 'android') { type Screens = Record; const SCREENS: Screens = { + DeleteAncestorOfExiting: { + screen: DeleteAncestorOfExiting, + title: '🆕 Deleting view with an exiting animation', + }, BasicLayoutAnimation: { screen: BasicLayoutAnimation, title: '🆕 Basic layout animation', diff --git a/Example/src/LayoutReanimation/DeleteAncestorOfExiting.tsx b/Example/src/LayoutReanimation/DeleteAncestorOfExiting.tsx new file mode 100644 index 00000000000..07400709a88 --- /dev/null +++ b/Example/src/LayoutReanimation/DeleteAncestorOfExiting.tsx @@ -0,0 +1,54 @@ +import Animated, { PinwheelOut } from 'react-native-reanimated'; +import { Button, StyleSheet, View } from 'react-native'; + +import React from 'react'; + +export function DeleteAncestorOfExiting() { + const [outer, setOuter] = React.useState(false); + const [inner, setInner] = React.useState(true); + + return ( + +