Open BeeMargarida opened 3 years ago
Hi, and thanks for sharing the elaborate example, that was very useful. I've added a test-case to the example
app and was able to reproduce similar problems. Both iOS and Android seem to be experiencing problems. I've had a closer look at the native iOS SafeAreaView
implementation in react-native-safe-area-context
and I sort of see what's going on. The problem is in the fact that <SafeAreaView>
needs an extra pass to the React Native UIManager and Yoga to set the padding
on the view. Both the iOS and Android implementations seem to do this in a similar way. This causes react-native-shared-element
to measure the size and position of the element before <SafeAreaView>
has applied its padding, causing the shift that you see.
I'm not really sure on how to fix this tbh. react-native-shared-element
measures your view as fast as possible (to prevent and flickering/ghost elements). For the best results you should construct your views in such a way that they don't require and re-layouting. And unfortunately <SafeAreaView>
causes such re-layouting, even though it is performed at the native level.
Hi, and thanks for sharing the elaborate example, that was very useful. I've added a test-case to the
example
app and was able to reproduce similar problems. Both iOS and Android seem to be experiencing problems. I've had a closer look at the native iOSSafeAreaView
implementation inreact-native-safe-area-context
and I sort of see what's going on. The problem is in the fact that<SafeAreaView>
needs an extra pass to the React Native UIManager and Yoga to set thepadding
on the view. Both the iOS and Android implementations seem to do this in a similar way. This causesreact-native-shared-element
to measure the size and position of the element before<SafeAreaView>
has applied its padding, causing the shift that you see.I'm not really sure on how to fix this tbh.
react-native-shared-element
measures your view as fast as possible (to prevent and flickering/ghost elements). For the best results you should construct your views in such a way that they don't require and re-layouting. And unfortunately<SafeAreaView>
causes such re-layouting, even though it is performed at the native level.
Thank you for you very fast response!
Just to get your opinion, would implement the safe area logic locally (use the insets initialWindowMetrics
from "react-native-safe-area-context" as padding for the view of each screen) solve this problem?
Not sure, but I would definitely try 👍
Alternatively, you could try caching the insets so that they are immediately available when your view is rendered for the first time.
Alternatively, you could try caching the insets so that they are immediately available when your view is rendered for the first time.
It seems caching does not seem to work as well. Either way, thank you!
https://github.com/th3rdwave/react-native-safe-area-context#usesafeareainsets works for me
import {useSafeAreaInsets} from "react-native-safe-area-context";
const insets = useSafeAreaInsets();
const Screen = () => {
return (
<View style={{
flex: 1,
paddingTop: insets.top,
paddingLeft: insets.left,
paddingRight: insets.right,
paddingBottom: insets.bottom
}}>
<SharedElement id="itemId">
</SharedElement>
</View>
);
};
The navigation option headerShown:false makes the offset and jump bigger when using <SafeAreaView>
Creating a view as suggested above with padding solves the issue for me :)
Having this issue as well, would be great to see a solution. Specifically with the KeyboardAvoidingView
First of all, thank you for this amazing library!
I found an issue in iOS when using
SafeAreaView
(both fromreact-native
andreact-native-safe-area-context
) with SharedElements. Without the SafeAreaView it works well. When making the animation, there is a little "jump", where the final place of the animation is off by some offset.The code can be found and it's runnable in https://github.com/BeeMargarida/react-navigation-shared-element, it's the last example (sorry for the quality of the code, it was a testing scenario made really fast).
Code
``` import { NavigationContainer } from "@react-navigation/native"; import { createStackNavigator } from "@react-navigation/stack"; import React from "react"; import { Button, View } from "react-native"; import { SafeAreaProvider, SafeAreaView } from "react-native-safe-area-context"; import { SharedElement, createSharedElementStackNavigator, } from "react-navigation-shared-element"; const Stack = createStackNavigator(); const SharedElementStack = createSharedElementStackNavigator(); const forFade = ({ current, closing }) => ({ cardStyle: { opacity: current.progress, }, }); const Screen1 = (props: any) => { return (https://user-images.githubusercontent.com/25725586/130613627-91929813-9b74-491c-a59a-3220db436186.mp4