react-native-screens
react-native-screens copied to clipboard
No back animations on iOS, instant transitions only
Workaround found:
The problem was I was using use_frameworks!
in my Podfile
.
The exact line I had was use_frameworks! :linkage => :static
This was because the new react-native-firebase libraries (15.x.x) required this (all react-native-firebase > 14.x.x). For some reason this also made back animations stopped working.
I fixed this by downgrading react-native-firebase to 14.11.1 and removing use_frameworks!
from my Podfile. Then I deleted the pods folder and reinstalled. Everything now works.
Description
UPDATE:
- To fully replicate you must copy over the Podfile
UDPATE:
- Appears to have something to do with using an
Animated.View
SplashScreen component, using a regularView
doesn't interfere with the transitions
I updated to react native 0.69.1 and then I found that I no longer get back animations, the view in front disappears instantly.
- I've tried using both
useNavigation()
and({navigation})
in the screens arguments to triggergoBack()
. There's still no transition animation either way - Swiping the page off works fine
- If I enable
headerShown: true
then using the native back button on iOS plays the animations as normal - I've downgraded back to react native 0.68 and I've still go the same issue
It's the same issue as https://github.com/software-mansion/react-native-screens/issues/1356
Screenshots
https://user-images.githubusercontent.com/21344181/179496474-6fa6c511-49ea-443e-9be7-33a027597716.MP4
Steps To Reproduce
- Go back using
goBack()
(as opposed to a native back button).
Expected behavior
The transition should just play as normal
Actual behavior
There is no back animation when using goBack()
Reproduction
UPDATE: Reproduce this issue with the following code:
App.tsx
import * as React from 'react';
import {useEffect, useState} from 'react';
import {View, TouchableOpacity, Text} from 'react-native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import {NavigationContainer} from '@react-navigation/native';
import Animated, {FadeOut} from 'react-native-reanimated';
const MainStack = createNativeStackNavigator();
function App() {
const [userLoading, setUserLoading] = useState(true);
useEffect(() => {
setUserLoading(false);
}, []);
// Just show a splashscreen if either are loading
if (userLoading) {
return <SplashScreen />;
}
return (
<NavigationContainer>
<MainStack.Navigator>
<MainStack.Screen name={'FirstScreen'} component={FirstScreen} />
<MainStack.Screen name='SecondScreen' component={SecondScreen} />
</MainStack.Navigator>
</NavigationContainer>
);
}
const FirstScreen = ({navigation}: any) => {
return (
<View style={{flex: 1, alignContent: 'center', justifyContent: 'center'}}>
<TouchableOpacity
style={{backgroundColor: 'cyan', padding: 20}}
onPress={() => navigation.navigate('SecondScreen')}
>
<Text>Go forward</Text>
</TouchableOpacity>
</View>
);
};
const SecondScreen = ({navigation}: any) => {
return (
<View style={{flex: 1, alignContent: 'center', justifyContent: 'center'}}>
<TouchableOpacity
style={{backgroundColor: 'magenta', padding: 20}}
onPress={() => navigation.goBack()}
>
<Text>Go Back</Text>
</TouchableOpacity>
</View>
);
};
const SplashScreen = () => {
return (
<Animated.View
style={{
backgroundColor: 'black',
flex: 1,
}}
exiting={FadeOut}
/>
);
};
export default App;
Podfile
require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
platform :ios, '13.0'
use_frameworks! :linkage => :static
target 'flashingscreens' do
config = use_native_modules!
# Flags change depending on the env values.
flags = get_default_flags()
use_react_native!(
:path => config[:reactNativePath],
# to enable hermes on iOS, change `false` to `true` and then install pods
:hermes_enabled => true,
:fabric_enabled => flags[:fabric_enabled],
# An absolute path to your application root.
:app_path => "#{Pod::Config.instance.installation_root}/.."
)
target 'flashingscreensTests' do
inherit! :complete
# Pods for testing
end
post_install do |installer|
# https://github.com/facebook/react-native/issues/32451
installer.pods_project.targets.each do |target|
if target.name == 'RCT-Folly'
target.build_configurations.each do |config|
config.build_settings['HEADER_SEARCH_PATHS'] = "$(inherited) ${PODS_ROOT}/fmt/include"
end
end
end
end
end
Platform
- [x] iOS
- [ ] Android
- [ ] Web
- [ ] Windows
- [ ] tvOS
Architecture
- [ ] Paper
- [ ] Fabric
Workflow
- [ ] Managed workflow
- [x] Bare workflow
Package versions
"@react-navigation/native": "^6.0.11", "@react-navigation/native-stack": "^6.7.0",
package | version |
---|---|
react-native | 0.69.1 |
@react-navigation/native | 6.0.11 |
@react-navigation/native-stack | 6.7.0 |
react-native-screens | 3.13.1 |
react-native-safe-area-context | 4.3.1 |
react-native-gesture-handler | 2.4.2 |
react-native-reanimated | 2.9.1 |
I have tried earlier versions of react, react native, reanimated, native-stack
Hey @fahadfj!
Would you try using [email protected]
? It is highly likely that this issue was already fixed, especially that [email protected]
does not have support for [email protected]
.
Edit: also you should upgrade react-native-gesture-handler
to 2.5.x
as it is first version with official support to 0.69.x I believe
Let me know if bumping the version resolved the issues.
Hey @kkafar ,
Thanks for taking this on, I've updated the libraries but sadly still the same issue (both screens and gesture handler).
Ok, it gets interesting now ;D
The fact that intrigues me the most right now is that you restored your code to earlier version and the issue persisted. This points towards some cache problem. After restoring your project to previous version (the version that still worked correctly) you should try:
- Removing pods completely & reinstalling them:
cd ios && rm -fr Pods build Podfile.lock && pod install && cd ..
. This step is important, because everytime you change minor version ofreact-native-screens
most likely native code changes -> it is reasonable to reinstall the pods and build the native code from scratch. - Reset your bundler cache:
yarn start --reset-cache
(or equivalent) - Make sure, that package versions in your
yarn.lock
respond package versions from yourpackage.json
file.
Sadly, without reproduction I can't be of much more help for now.
@kkafar I tried this but sadly it's the same issue.
If I can't create a minimal repro then what are my options? This is one of the most baffling bugs I've come across. I've been at it around 4 full days now
Also: While not minimal by any means I'd be willing to privately share the project (sans our private API keys).
Can anyone advise how I could create a repro of this? We're a production app and falling behind atm, any advice/help would be appreciated
Unfortunately I don't really know what might cause issues in your case as animations work properly on fresh applications & our example apps -> however it is possible, I doubt that this issue is caused only by react-native-screens
.
I know it sounds ridiculous & naive, but these things sometimes work:
- Create new branch,
git reset
to last working version. Clear all cache you can think of (remove pods, node_modules) & re-install and try to run. - Maybe try to clone fresh repo & run there?
Moreover, have you used Fabric with 0.69.1? If so, maybe you added (and did not remove) some Fabric specific configuration which causes this buggy behaviour?
I tried this and it seems to be still there.
What's the difference between navigation.goBack()
and the native back button that appears in headerShown: true
?
I have found that if I use a regular stack navigator (not native), I get all the correct animations, BUT I cannot interact with the app anymore after I goBack()
. If I use the react native inspector I cannot click anything either. What's going on here? Perhaps related https://github.com/software-mansion/react-native-screens/issues/21?
@fahadfj I've tried reproduction you provided, but it works fine for me... :(
https://user-images.githubusercontent.com/50801299/180756554-9ae7637c-7e5e-4cfe-90ac-0b9b5a77032f.mov
@kkafar I've tried again and I can reproduce it, have you used the same packages I'm using? AppDelegate.m
AppDelegate.m
#import "AppDelegate.h"
#import <AVFoundation/AVFoundation.h> // import
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <React/RCTLinkingManager.h>
#ifdef FB_SONARKIT_ENABLED
#import <FlipperKit/FlipperClient.h>
#import <FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.h>
#import <FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.h>
#import <FlipperKitNetworkPlugin/FlipperKitNetworkPlugin.h>
#import <SKIOSNetworkPlugin/SKIOSNetworkAdapter.h>
#import <FlipperKitReactPlugin/FlipperKitReactPlugin.h>
// LINKING
#import <React/RCTLinkingManager.h>
static void InitializeFlipper(UIApplication *application) {
FlipperClient *client = [FlipperClient sharedClient];
SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults];
[client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]];
[client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]];
[client addPlugin:[FlipperKitReactPlugin new]];
[client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]];
[client start];
}
#endif
#if RCT_DEV
#import <React/RCTDevLoadingView.h>
#endif
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil]; // allow
#ifdef FB_SONARKIT_ENABLED
InitializeFlipper(application);
#endif
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:@"waProject"
initialProperties:nil];
rootView.backgroundColor = [UIColor colorWithRed: 0.15 green: 0.14 blue: 0.12 alpha: 1.00];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
return YES;
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
#else
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}
// DEEP LINKING
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
return [RCTLinkingManager application:application openURL:url options:options];
}
// UNIVERSAL LINKING
- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity
restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
{
return [RCTLinkingManager application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
}
@end
https://user-images.githubusercontent.com/21344181/180776584-5d3df6ca-6807-4c19-8c4f-85ff5c93c396.mov
@kkafar you must you use the Podfile provided in the original post, I have now replicated this in a fresh new react native project and I get the flashing
@fahadfj Great to hear that you figured it out.
I've just looked at firebase website and found this paragraph (notice the blue note). I guess you have seen it already, but it nudges me towards opinion that this issue has broader scope than react-native-screens
, however we will look into this.
Hi, I used:
[ "expo-build-properties", { "ios": { "useFrameworks": "static" } } ], "@react-native-firebase/app",
for use firebase in development build, and also had problems with react-navigation animations. After deleting that - all done
#https://github.com/react-navigation/react-navigation/issues/10843
I am having the same issue.
I had to add use_frameworks
because of the react-native firebase upgrade.
I am curious why use_frameworks
is breaking the animations in react-native-screens.
Why is this issue closed? Is the only solution to downgrade any packages that requires use-frameworks
?
This issue is effectively blocking people who use react-native-firebase from upgrading to >= rnfb@15 and subsequently >= [email protected]. As the firebase-ios-sdk is not planning to remove use_frameworks, the only way forward for folks in this situation is to resolve why use_frameworks causes a break in animations. Can this be re-opened @kkafar?
Can we get a response from a maintainer here? Is there something else needed for us to re-open? Judging by the upvotes the previous comment got, my guess is this issue is pervasive in many dependent codebases.
The workaround posed here is not sufficient to support an upgrade path for react native apps relying on use_frameworks, which will be around for some time still.
Expo users are also now on a faster upgrade clock as SDK releases are happening every few months now, and thus deprecations happening quicker as well. If this is not resolved soon, many expo devs are going to be phased out of supported versions.
TLDR this is a serious issue that should be given at least a second look to determine if react-native-screens is the culprit, and if not, a path to which library is. Happy to help in any way I can. I believe the first step is re-opening the ticket.
I'll try to look into it
Any news or progress regarding this?
Just to be clear - because of Firebase we need to add use_frameworks
and this breaks the animation?
I'm on React Native 0.69.3. Does this issue still exist on newer React Native versions?
Just to be clear - because of Firebase we need to add
use_frameworks
and this breaks the animation? I'm on React Native 0.69.3. Does this issue still exist on newer React Native versions?
Since my last test on expo sdk 47 (0.70.5), yes use_frameworks breaks the animation. As of firebase-ios-sdk 9 (rnfb 15), use_frameworks is required.
Just noticed something - don't know if this helps with anything but here goes: When having "Debug with Chrome" enabled, the back transition animations are working.
any luck?
@miladdev85 I confirm I have the same issue. back animation works only when I enable debug mode. Sharing my package.json dependencies. "dependencies": { "@expo/vector-icons": "^13.0.0", "@invertase/react-native-apple-authentication": "^2.2.2", "@killerwink/lottie-react-native-color": "^1.0.2", "@react-native-firebase/app": "^16.6.0", "@react-native-firebase/auth": "^16.7.0", "@react-native-firebase/messaging": "^16.7.0", "@react-native-google-signin/google-signin": "^9.0.2", "@react-navigation/bottom-tabs": "^6.5.3", "@react-navigation/native": "^6.1.2", "@react-navigation/native-stack": "^6.9.8", "@reduxjs/toolkit": "^1.9.1", "@types/lodash": "^4.14.191", "axios": "^1.2.4", "expo": "~47.0.12", "expo-asset": "~8.7.0", "expo-build-properties": "~0.4.1", "expo-constants": "~14.0.2", "expo-dev-client": "~2.0.1", "expo-device": "~5.0.0", "expo-font": "~11.0.1", "expo-linking": "~3.3.0", "expo-splash-screen": "~0.17.5", "expo-status-bar": "~1.4.2", "expo-store-review": "~6.0.0", "expo-system-ui": "~2.0.1", "expo-updates": "~0.15.6", "expo-web-browser": "~12.0.0", "lodash": "^4.17.21", "lottie-react-native": "5.1.4", "react": "18.1.0", "react-devtools": "^4.27.1", "react-dom": "18.1.0", "react-native": "0.70.5", "react-native-gesture-handler": "~2.8.0", "react-native-purchases": "^5.8.0", "react-native-reanimated": "~2.12.0", "react-native-responsive-screen": "^1.4.2", "react-native-safe-area-context": "4.4.1", "react-native-screens": "~3.18.0", "react-native-ui-lib": "^6.28.3", "react-native-web": "~0.18.7", "react-query": "^3.39.2", "react-redux": "^8.0.5", "redux": "^4.2.0", "redux-persist": "^6.0.0", "redux-persist-expo-filesystem": "^2.0.0", "redux-thunk": "^2.4.2" }, "devDependencies": { "@babel/core": "^7.19.3", "@types/react": "~18.0.24", "@types/react-native": "~0.70.5", "jest": "^26.6.3", "jest-expo": "^47.0.0", "react-test-renderer": "18.1.0", "typescript": "^4.6.3" }
A user on Reddit had issues with use_frameworks
and solved it by using https://github.com/joncardasis/cocoapods-user-defined-build-types
This plugin allows for a Podfile to specify how each Pod (or multiple Pods) should be built (ex. as a dynamic framework).
And this is his Podfile which he helpfully posted on Reddit:
plugin 'cocoapods-user-defined-build-types'
require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
platform :ios, '11.0'
$RNFirebaseAsStaticFramework = true
enable_user_defined_build_types!
target 'ProjectName' do
config = use_native_modules!
pod "Firebase", :build_type => :dynamic_framework
pod "FirebaseCoreInternal", :build_type => :dynamic_framework
pod "FirebaseCore", :build_type => :dynamic_framework
pod 'GoogleUtilities', :build_type => :dynamic_framework
use_react_native!(
:path => config[:reactNativePath\],
# to enable hermes on iOS, change `false` to `true` and then install pods
:hermes_enabled => true
)
use_flipper!({ 'Flipper' => '0.171.0' })
post_install do |installer|
react_native_post_install(installer)
# Disable arm64 builds for the simulator
installer.pods_project.build_configurations.each do |config|
config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
end
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['ENABLE_BITCODE'] = 'NO'
end
end
end
end
I'm going to try this out today and hopefully this can be a workaround for this issue...
Thanks, @miladdev85 ! Please let us know how it goes.
@fa2id I don't know what this exactly does or what the cons are, but animations are working now 🥳 @austin43 @mehthabux You guys might wanna give this a try also?
I'm not 100% sure what it does on the side of Firebase, but I managed to fix this issue by removing use_framework
(like everyone else) and adding these two lines in my Podfile
:
pod 'FirebaseCore', :modular_headers => true
pod 'GoogleUtilities', :modular_headers => true
@RaphBlanchet RNFB maintainer recommends against this approach, as it could have undesired effects https://github.com/invertase/react-native-firebase/issues/6332#issuecomment-1287884131