software-mansion / react-native-reanimated

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

Layout animations break stack navigation on iOS #2639

Closed lachenmayer closed 2 years ago

lachenmayer commented 2 years ago

Description

Hey folks πŸ‘‹, I have been trying to debug an issue in our app with @mrousavy that was introduced by upgrading to the Reanimated v2.3.0 beta and adding layout animations. (Layout animations are amazing otherwise btw, such a fantastic API & super performant!)

In some cases when navigating between screens in our app inside a @react-navigation/stack navigator, it seems that views which have entering/exiting layout animations remain on screen after navigating. This issue only appears on iOS.

You can see the behavior in this video:

https://user-images.githubusercontent.com/38614/142255392-d71fe338-a397-4a80-8cb2-3bde1a3c1fc2.mp4

What's happening in this video:

  1. At 0:03, I am triggering a navigation to the chat screen. This works as expected. βœ…
  2. At 0:06, I am triggering another navigation to a different chat screen. This does not work. ❌

Interestingly, it is still possible to navigate away from this screen using swipe gestures, and the scroll view (the big white box in the middle) is still scrollable.

(We are not using @react-navigation/native-stack, for reasons unrelated to this. However, @react-navigation/stack does use the react-native-screens containers if they are available.)

Minimal code example

Our app is not open source, so I tried reproducing this issue using the Reanimated 2 playground as a starting point.

Check out the repro here: https://github.com/lachenmayer/reanimated-2-playground/pull/1

https://user-images.githubusercontent.com/38614/142256817-962a4e3e-dce2-42a4-beaf-366f00f2dd78.mov

  1. There are 2 screens, "First" and "Second"
  2. You can navigate from the first screen by pressing "click me". βœ…
  3. A Reanimated.View with a 10-second FadeIn entering & exiting animation is rendered. βœ…
  4. You can navigate back by tapping the header. βœ…
  5. You can not press the "click me" until 10 seconds have occurred. ❌

I am not 100% sure if this is actually the same bug - but in any case, the component containing the exiting animation is lingering in the view hierarchy.

If I enable "Debug view hierarchy" in XCode while the button is not tappable, I can see that the component which had the layout animation on it covers the entire screen:

Screen Shot 2021-11-17 at 18 09 37

(Strangely, if I try to use "Debug view hierarchy" in the real app, it just times out...)

Possibly related PRs

2581 - this adds some special handling for react-native-screens to REAUIManager.mm. I don't really understand what's going on here, but it could be that this logic is incorrect?

2617 - this disables the disappearing animations for the native stack, but only on Android. Is a similar fix necessary for iOS?

Package versions

Affected platforms

Let me know if I can provide any further information - would appreciate any help with this, thanks a lot!

github-actions[bot] commented 2 years ago

Issue validator

The issue is invalid!

Sanglepp commented 2 years ago

I have mentioned the stack navigator issue with layout animations in https://github.com/software-mansion/react-native-reanimated/issues/2538

There are some fixes implemented in the https://github.com/software-mansion/react-native-reanimated/pull/2581 but I tested these changes and the stack navigation back navigation still keeps a transparent orphaned view above the correct screen.

For me this is a huge blocker and I now ditched LayoutAnimations implementation and will implement the animations separately.

lachenmayer commented 2 years ago

Yes, those fixes do not work for us either - I'm still not sure whether our original bug (ie. the partially rendered views covering the whole screen) is actually the same issue.

But at least we have an easy repro of the transparent view issue now. :)

WoLewicki commented 2 years ago

Can you check if https://github.com/software-mansion/react-native-reanimated/pull/2647 resolves the problem?

lachenmayer commented 2 years ago

Thanks a lot for trying to fix this - this does not fix our internal issue unfortunately. I'll try to see on Monday if it fixes the playground repro I posted. This could definitely indicate that these are two separate bugs.

Sanglepp commented 2 years ago

Can you check if #2647 resolves the problem?

@WoLewicki This solved the issue for me. Thanks a lot!

lachenmayer commented 2 years ago

Can confirm the transparent view issue is fixed in the repro here: https://github.com/lachenmayer/reanimated-2-playground/pull/1/commits/7846b3b54244fb4f1c6fe3f32f8c532bece87d03

How do you want me to proceed with the original issue, should I remove bits about the transparent view in this issue, or open a separate one?

Thanks a lot for taking a look!

WoLewicki commented 2 years ago

@lachenmayer I think the only way we could take care of it is for you to make a small repro with only necessary components, without any other logic, so everyone can test it. I think providing it in a new issue would be a good option. If you could ping me there, it would be probably best.

alexking commented 2 years ago

If this issue is still giving anyone trouble, be sure that you're running the latest version of react-native-screens - 2.x releases (specifically 2.18.1) seem to not work with this fix because toRemoveChild will never be a RNSScreenView.