Stefan Falk
Stefan Falk

Reputation: 25487

Stack.Navigator header appears offset from the top on iPhone 14 pro

In my React Native app I am using <SafeAreaView> (react-native) together with Stack.Navigator (@react-navigation/native-stack). On most devices so far, I didn't have any issues with the following approach but at least in one occassion, particularly on an iPhone 14 pro, we discovered that the header appears to be not where it should be.

I cannot explain the reason behind it but it looks as if some padding pushes the header content beyond the space where it should be located. What we then see is an empty area where the header is supposed to be but also a small gap below it.

Please take a look at the following screenshot.

Model: iPhone 14 pro

App header appears offset from the top causing a gap between the unexplained header and the actual header itself.

App.tsx

The main entry point of the app orders the componens like this:

<SafeAreaProvider>
  <SafeAreaView>
    <StatusBar />
    <Stack.Navigator />
  </SafeAreaView>
</SafeAreaProvider>

This is how it is implemented:

const AppMain = () => {
  const { firebaseUser } = useContext(PrincipalContext);
  const theme = useTheme();

  return (
    <SafeAreaView className="flex w-full h-full">
      <StatusBar
        barStyle={theme.dark ? 'light-content' : 'dark-content'}
        backgroundColor={theme.colors.background}
      />
      <KeyboardAvoidingView
        className="flex w-full h-full"
        behavior={Platform.OS === 'ios' ? 'padding' : 'height'}>
        <AppNavigationContainer>
          <OverlayDialogContextProvider>
            {firebaseUser ? <MainStack /> : <AuthStack />}
          </OverlayDialogContextProvider>
        </AppNavigationContainer>
      </KeyboardAvoidingView>
    </SafeAreaView>
  );
};

const queryClient = new QueryClient();
const App = () => {
  return (
    <SafeAreaProvider>
      <QueryClientProvider client={queryClient}>
        <GestureHandlerRootView className="flex w-full h-full">
          <PrincipalContextProvider>
            <PaperThemeContextProvider>
              <AppMain />
            </PaperThemeContextProvider>
          </PrincipalContextProvider>
        </GestureHandlerRootView>
      </QueryClientProvider>
    </SafeAreaProvider>
  );
};

export default App;

Here, <MainStack /> and <AuthStack /> are just representatives for <Stack.Navigator />.

MainStack.tsx

This is, for example, how I am using the Stack.Navigation

const ProfileIconButton = () => {
  const navigation = useNavigation<any>();
  return <IconButton icon="account" onPress={() => navigation.push('Profile')} />;
};


export const MainStack = () => {
  const navigation = useNavigation<any>();
  const theme = useTheme();
  return (
    <>
      <Stack.Navigator
        initialRouteName="MyTours"
        screenOptions={{
          contentStyle: { backgroundColor: theme.colors.background },
          headerShown: true,
          headerRight: ProfileIconButton,
          headerTitleStyle: {
            color: theme.colors.onBackground,
          },
          headerStyle: {
            backgroundColor: theme.colors.background,
          },
        }}>
        <Stack.Screen
          name="MyTours"
          component={MyToursScreen}
          options={{
            title: '',
            headerShown: true,
          }}
        />
      </Stack.Navigator>
    </>
  );
};

As mentioned, so far I have not seen this issue on any other devices like a Samsung A55 or the iPhone X.

What am I missing here?

Upvotes: 0

Views: 32

Answers (0)

Related Questions