th3rdwave / react-native-safe-area-context

A flexible way to handle safe area insets in JS. Also works on Android and Web!
MIT License
2.17k stars 200 forks source link

Flicker in the middle of navigation animation #219

Closed gunnartorfis closed 1 year ago

gunnartorfis commented 3 years ago

When navigating to a new screen, a short flicker/jump appears. I am using SafeAreaProvider wrapped around the rest of my app and then using SafeAreaView at the root of my screens.

https://user-images.githubusercontent.com/5333875/138173288-c2dbd192-68eb-40e9-9745-4fab8a529da0.mov

tommycarpi commented 2 years ago

I managed to fix it by using useSafeAreaInsets and <View> instead of <SafeAreaView>

const insets = useSafeAreaInsets();

<View
      style={{
        paddingTop: insets.top,
        paddingBottom: 0,
        paddingLeft: insets.left,
        paddingRight: insets.right
      }}>
</View>
neiker commented 2 years ago

Seems to be a bug on native implementation only: https://github.com/th3rdwave/react-native-safe-area-context/blob/main/src/SafeAreaView.native.tsx

Importing web implementation works like expected on native https://github.com/th3rdwave/react-native-safe-area-context/blob/main/src/SafeAreaView.tsx

federicogomezlara commented 2 years ago

I managed to fix it by using useSafeAreaInsets and <View> instead of <SafeAreaView>

const insets = useSafeAreaInsets();

<View
      style={{
        paddingTop: insets.top,
        paddingBottom: 0,
        paddingLeft: insets.left,
        paddingRight: insets.right
      }}>
</View>

I took the same approach, it works perfectly, just as Safe Area View should by default

m-sterspace commented 2 years ago

For the lazy here's a fully fleshed out alternative component:

SafeAreaViewFixed.tsx


import React, { ReactNode } from 'react';
import { StyleProp, StyleSheet, View, ViewProps, ViewStyle } from 'react-native';
import { Edge, useSafeAreaInsets } from 'react-native-safe-area-context';

type Props = {
  children: ReactNode;
  style?: StyleProp<ViewStyle>;
  edges?: readonly Edge[] | undefined;
} & ViewProps;

/**
 * USE THIS - Alternative to the default [SafeAreaView](https://github.com/th3rdwave/react-native-safe-area-context#safeareaview)
 * from react-native-safe-area-context which currently has an issue that will cause a flicker / jump on first render on iOS / Android.
 *
 * [SafeAreaProvider](https://github.com/th3rdwave/react-native-safe-area-context#safeareaprovider) should still be higher in the tree.
 *
 * GitHub issues:
 * [219](https://github.com/th3rdwave/react-native-safe-area-context/issues/219),
 * [226](https://github.com/th3rdwave/react-native-safe-area-context/issues/226)
 */
export default function SafeAreaViewFixed({ children, style, edges, ...rest }: Props) {
  const insets = useSafeAreaInsets();
  const defaultEdges = edges === undefined;
  return (
    <View
      style={StyleSheet.compose(
        {
          paddingTop: defaultEdges || edges?.includes('top') ? insets.top : undefined,
          paddingBottom: defaultEdges || edges?.includes('bottom') ? insets.bottom : undefined,
          paddingLeft: defaultEdges || edges?.includes('left') ? insets.left : undefined,
          paddingRight: defaultEdges || edges?.includes('right') ? insets.right : undefined,
        },
        style,
      )}
      {...rest}
    >
      {children}
    </View>
  );
}
jamonholmgren commented 2 years ago

@m-sterspace Thanks -- your code fixed a long-standing issue in the new GasBuddy RN app. It'll impact millions. :-)

(And thanks to @tommycarpi for finding the original solution of course.)

varunvasudeva1 commented 2 years ago

@tommycarpi Had this issue for months now and nothing I tried seemed to fix it, except this - thanks a ton!

jacobp100 commented 1 year ago

This is documented in the readme

wouterds commented 1 year ago

Can't we adopt the component by @m-sterspace into the actual package? Why ship a SafeAreaView that doesn't properly work?

jacobp100 commented 1 year ago

The safe area view component does work. The hooks have a documented delay we can’t work around yet

mleister97 commented 1 year ago

@jacobp100 I am still facing the flickerin issues in end 2023. The solution of @m-sterspace works for me, thank you so much. There is currently no other solution working for me (tested on Android 10)

MaratSHU commented 11 months ago

Hi! I catch similar issue on adding autofocus to TextInput on ios (didn't check on android yet). So I prepare two screens and on second screen add <TextInput autoFocus/>. On navigating to second screen it cause flickering. Turning off autofocus - works as expected.

JClackett commented 9 months ago

Still have this issue, using the hook and apply styles manually stops it

badaz commented 9 months ago

I've been struggling with this issue for some months now. What I don't understand is that using SafeAreaView from this lib used to work built in and without this flicker problem. I've first encountered the problem when migrating to RN 0.72 I think but I can not really assert who is faulty, this lib? react-native? my nav lib (RNN wix)? When reading this issue it seems the problem comes from this lib, however I tried downgrading it, although staying on RN 0.72, but it did not solve the problem for me. So what has changed?

gkpo commented 8 months ago

Also still have this issue. I had to use @m-sterspace 's fixed component. Not ideal but will do the trick for now. Any ideas why this could be happening ? Any fixed planned ?

melyux commented 3 weeks ago

Can you reopen this @jacobp100?