react-native-screens
react-native-screens copied to clipboard
[iOS] bug with @react-navigation/bottom-tabs - initial jumping
Description
When using @react-navigation/bottom-tabs with RNS, the content jumps on tab change (one the first render only). I made sure I've tested this plenty of times.
The bug does not occur if I import
import { createStackNavigator } from '@react-navigation/stack';
but with
import { createNativeStackNavigator } from '@react-navigation/native-stack';
My whole is wrapped with SafeAreaProvider
from react-native-safe-area-context
like so:
import {
SafeAreaProvider,
initialWindowMetrics
} from 'react-native-safe-area-context';
<SafeAreaProvider initialMetrics={initialWindowMetrics}>
<Navigator theme={combinedTheme} />
</SafeAreaProvider>
I also tried to test it without initialMetrics and also used SafeAreaView
(from react-native-safe-area-context and react-native), but it still jumped for me.
I also patched react-navigation bottoms tabs with this PR applied by @WoLewicki https://github.com/react-navigation/react-navigation/pull/9772
But the jump still occur. Also made sure to disable/enable freeze etc. I couldn't manage to prevent the initial jumping. See my video attached.
Screenshots
I created a dead simple preview, see my Video below. Please watch the in the center. https://streamable.com/i7upqv
Expected behavior
Should not jump on initial render
Actual behavior
It jumps on initial render and it does look weird
Reproduction
Happens on iOS, snack not helping here.
Platform
- [X] iOS
- [ ] Android
- [ ] Web
- [ ] Windows
- [ ] tvOS
Workflow
- [X] Managed workflow
- [X] Bare workflow
Package versions
package | version |
---|---|
react-native | 0.64.3 |
@react-navigation/native | 6.0.6 |
@react-navigation/native-stack | 6.2.5 |
react-native-screens | 3.10.1 |
react-native-safe-area-context | 3.3.2 |
react-native-gesture-handler | 2.1.0 |
react-native-reanimated | 2.3.1 |
expo | 44.0.3 |
Expo CLI 5.0.3 environment info:
System:
OS: macOS 11.6.1
Shell: 5.8 - /bin/zsh
Binaries:
Node: 14.18.2 - /usr/local/opt/node@14/bin/node
Yarn: 1.22.17 - /usr/local/bin/yarn
npm: 6.14.15 - /usr/local/opt/node@14/bin/npm
Watchman: 2021.12.06.00 - /usr/local/bin/watchman
Managers:
CocoaPods: 1.11.2 - /usr/local/bin/pod
SDKs:
iOS SDK:
Platforms: DriverKit 21.2, iOS 15.2, macOS 12.1, tvOS 15.2, watchOS 8.3
IDEs:
Android Studio: 4.1 AI-201.8743.12.41.6953283
Xcode: 13.2.1/13C100 - /usr/bin/xcodebuild
npmPackages:
react-dom: 17.0.2 => 17.0.2
react-native-web: 0.17.5 => 0.17.5
npmGlobalPackages:
eas-cli: 0.41.1
expo-cli: 5.0.3
Expo Workflow: bare
P.S: I thought this is the right repo to post this issue. If you feel I have to post this at react-navigation, let me know.
Can you post this simple repo with the changed applied with e.g. patch-package
so we can work on it?
@WoLewicki I got rid of it with headerTransparent:true + remove of initialMetrics and some refactoring of my navigators, but I still think that this is bug, because it does not work with all combinations.
Hmm if you think this is a bug on react-native-screens
side, please provide a reproduction so we can work on it.
@WoLewicki I will provide a reproduction soon. I think it is indeed a bug on rns.
@WoLewicki
Here is repo with reproduced bug: https://github.com/pt7892/rnscreens-bottom-tab-flicker
also videos:
https://user-images.githubusercontent.com/20343932/151573753-31677bc2-078f-4697-8fe5-ed64f1f3e1aa.mp4
https://user-images.githubusercontent.com/20343932/151573647-f13466e2-cbf4-4080-bb08-7355ca1c4255.mov
If initial tab screen is simple, you may not notice this, thats why i added bunch of Text
and Button
components
From what i understand, on tab change, if stack is being mounted first time, 2 RNScreen
are being layout on screen, but not in same "tick", and thats why you may notice this flash effect
@pt7892 is the jumping behavior connected to the flicker issue you posted here?
@WoLewicki
Actually, i was referring to this issue GH-1276, but mistakenly added comment on this one.
I see now that reproduction repo is already uploaded in GH-1276, so this comment can be deleted.
Sorry for the mistake
I also have the similar issue. But it happens not only in Initial rendering. It happens every time when I go or come back to the screen inside BottomTabNavigator.
My packages:
"@react-navigation/bottom-tabs": "^6.2.0", "@react-navigation/elements": "^1.3.1", "@react-navigation/material-top-tabs": "^6.1.1", "@react-navigation/native": "^6.0.8", "@react-navigation/native-stack": "^6.5.0", "react-native-reanimated": "^2.4.1", "react-native-safe-area-context": "^3.3.2", "react-native-screens": "3.11.0",
@hirbod Do you have a workaround for it?
@vladyslavNiemtsev please provide a reproduction of this issue then so we can work on it, otherwise we cannot do much about it.
hey, when I set headerTransparent: true
as described here: https://github.com/software-mansion/react-native-screens#solution
The problem with jumping is gone on Android.
But I still have a problem with content cut off on Android.
I think this issue was about iOS
, so I am not sure what issue you are mentioning. Or am I missing something?
He is indeed right. It is also jumping on android. Only headerTransparent was helping for me
Just a small point here, if you have headerShown: false in your BottomTabNavigator when you enable it - jumping disappears
@WoLewicki this is still a thing. The issue comes from where you add headerShown or headerTranslucent.
If you use the header provided by BottomTab, there is no jumping. But when you have a nested stack as a tab, you don't want to use the header from the BottomTab, instead you wan't to use the header provided by the nested stack.
This jumping is still super annoying and there is no real way around it. It just looks like the insets where applied too late and thats what cause the drops. There are repos available in the issue tracker, there is even a duplicated issue: https://github.com/software-mansion/react-native-screens/issues/1276
Would be awesome if we could resolve this.
I tried to debug and solve this some time ago but I did not manage to find a solution. If you have any time frame to debug it, it would be really helpful.
Iām experiencing the same issue. It seems to be related to the headerShown
option. It only happens on first render as well.
With headerShown: false
:
https://user-images.githubusercontent.com/6510935/173461630-7ddb650d-5ee6-41c0-80de-fa1b8a8fea0d.MOV
With headerShown: true
:
https://user-images.githubusercontent.com/6510935/173461690-78c17f4b-0481-44c2-a100-dc724a1eabe2.MOV
I found a workaround for this. Instead of using SafeAreaView
you will need to style a View
component and use the useSafeAreaInsets
hook to set the appropriate padding:
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import PropTypes from 'prop-types';
import styled from 'styled-components/native';
const StyledView = styled.View`
background-color: black;
flex: 1;
padding-bottom: ${({ insets }) => insets.bottom}px;
padding-top: ${({ insets }) => insets.top}px;
`;
export const SafeAreaView = ({ children, ...otherProps }) => {
const insets = useSafeAreaInsets();
return (
<StyledView {...otherProps} insets={insets}>
{children}
</StyledView>
);
};
SafeAreaView.propTypes = {
children: PropTypes.node,
};
SafeAreaView.defaultProps = {
children: null,
};
useSafeAreaInsets
works for me
Fixed this by swapping <SafeAreaView />
with useSafeAreaInsets()
<View style={[styles.container, { paddingTop: Math.max(insets.top, 16) }]} {...otherProps}>
@sjransom see my comment here
You cannot use SafeAreaView
, you have to create a regular View
component and use the useSafeAreaInsets()
to pad it appropriately.
I've tried using the custom View
with useSafeAreaInsets()
and I've also tried not using any SafeAreaView
at all, and I'm still getting the glitching effect :(
@aymather please show the smallest reproducible example possible
@l0gicgate Ok so I've tried reproducing the problem... and of course... no dice... but I have recreated a very basic environment to demonstrate a working concept if anyone wants to view it / try to reproduce the problem from there. Here is the repository. (I'll also just add that this environment was created with npx react-native init [name]
)
I did, however, fix the problem in my app by upgrading react-native-screens
from 3.12.0
-> 3.3.0
.
Now... I thought that the version might have something to do with the problem, so when I first tried to reproduce the problem, the version that came in when i added react-native-screens
was 3.15.0
and the issue wasn't there. So I thought, oh ok.. it was probably something that was patched. So I then downgraded from 3.15.0
-> 3.12.0
to try to reproduce the problem. However, even after downgrading, I still was unable to get the glitch to happen...
For anyone who is still facing this issue, I'd say try removing the package from your project completely, and reinstalling it. Try the 3.3.0
version and see if that works too. Maybe a good-ole-fashioned rm -rf node_modules && rm yarn.json && yarn
is all that's needed..? š¤·š»āāļø
Any update on this? Can we have something like "headerTopInsetEnabled" from React Navigation V5 back?
Edit: After wrapping my App with <SafeAreaProvider><App/></SafeAreaProvider>
from react-native-safe-area-context it does not jump anymore (no more double height header for a sec).
Hey! š
The issue doesn't seem to contain a minimal reproduction.
Could you provide a snack or a link to a GitHub repository under your username that reproduces the problem?
I'm currently experiencing this issue. Tried all of the solutions above and no luck.
Any update on the above issue?
Facing the same issue!
Faced the same issue today
https://github.com/software-mansion/react-native-screens/issues/1251#issuecomment-1154533585
This solution worked