React Native iOS端SplashScreen.show()调用无效问题求助
问题:react-native-splash-screen在iOS端重新调用SplashScreen.show()无效
在使用react-native-splash-screen库时,遇到以下问题:在Home Screen中触发SplashScreen.show()时,Android端可正常重新显示启动屏,但iOS端完全无效果。当前iOS端原生初始化代码如下:
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; #if RCT_NEW_ARCH_ENABLED _contextContainer = std::make_shared<facebook::react::ContextContainer const>(); _reactNativeConfig = std::make_shared<facebook::react::EmptyReactNativeConfig const>(); _contextContainer->insert("ReactNativeConfig", _reactNativeConfig); _bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:bridge contextContainer:_contextContainer]; bridge.surfacePresenter = _bridgeAdapter.surfacePresenter; #endif NSDictionary *initProps = [self prepareInitialProps]; UIView *rootView = RCTAppSetupDefaultRootView(bridge, @"ProjectName", initProps); if (@available(iOS 13.0, *)) { rootView.backgroundColor = [UIColor systemBackgroundColor]; } else { rootView.backgroundColor = [UIColor whiteColor]; } self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; UIViewController *rootViewController = [UIViewController new]; rootViewController.view = rootView; self.window.rootViewController = rootViewController; [self.window makeKeyAndVisible]; [RNSplashScreen show]; return YES;
由于使用RNRestart.Restart()会出现白屏问题,需通过重新调用SplashScreen.show()避免该情况,急需解决iOS端的无效问题。
解决方案
1. 修复RNSplashScreen原生show方法
iOS端默认实现中,react-native-splash-screen仅在APP启动时创建一次启动屏视图,调用hide()后视图会被移除,后续show()无法重建视图。需修改RNSplashScreen.m中的show方法:
+ (void)show { dispatch_async(dispatch_get_main_queue(), ^{ // 移除已存在的启动屏视图 for (UIView *view in [UIApplication sharedApplication].keyWindow.subviews) { if ([view.accessibilityIdentifier isEqualToString:@"RNSplashScreen"]) { [view removeFromSuperview]; break; } } // 创建新的启动屏视图 UIView *splashView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds]; splashView.accessibilityIdentifier = @"RNSplashScreen"; // 加载启动屏图片(根据你的LaunchScreen配置调整,若用xib则替换为加载xib逻辑) UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"LaunchScreen"]]; imageView.frame = splashView.bounds; imageView.contentMode = UIViewContentModeScaleAspectFill; [splashView addSubview:imageView]; // 添加到窗口并置于顶层 [[UIApplication sharedApplication].keyWindow addSubview:splashView]; [[UIApplication sharedApplication].keyWindow bringSubviewToFront:splashView]; }); }
2. 确保RN端调用时机正确
在Home Screen组件挂载完成后调用show(),避免因视图未准备好导致无效:
import React, { useEffect } from 'react'; import { View, Text } from 'react-native'; import SplashScreen from 'react-native-splash-screen'; const HomeScreen = () => { useEffect(() => { // 重新显示启动屏 SplashScreen.show(); // 示例:3秒后隐藏启动屏 setTimeout(() => { SplashScreen.hide(); }, 3000); }, []); return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <Text>Home Screen</Text> </View> ); }; export default HomeScreen;
3. 替代方案:自定义启动屏管理类
若不想修改第三方库代码,可封装自定义iOS原生类控制启动屏:
// CustomSplashScreen.h #import <UIKit/UIKit.h> @interface CustomSplashScreen : NSObject + (void)show; + (void)hide; @end // CustomSplashScreen.m #import "CustomSplashScreen.h" @implementation CustomSplashScreen + (void)show { dispatch_async(dispatch_get_main_queue(), ^{ [self removeSplashView]; UIView *splashView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds]; splashView.tag = 1000; // 加载LaunchScreen.xib(若使用图片则替换为UIImageView逻辑) UIView *launchView = [[[NSBundle mainBundle] loadNibNamed:@"LaunchScreen" owner:nil options:nil] firstObject]; launchView.frame = splashView.bounds; [splashView addSubview:launchView]; UIWindow *window = [UIApplication sharedApplication].keyWindow; [window addSubview:splashView]; [window bringSubviewToFront:splashView]; }); } + (void)hide { dispatch_async(dispatch_get_main_queue(), ^{ [self removeSplashView]; }); } + (void)removeSplashView { UIWindow *window = [UIApplication sharedApplication].keyWindow; for (UIView *view in window.subviews) { if (view.tag == 1000) { [view removeFromSuperview]; break; } } } @end
在RN端通过NativeModules调用:
import { NativeModules } from 'react-native'; const { CustomSplashScreen } = NativeModules; // 显示启动屏 CustomSplashScreen.show(); // 隐藏启动屏 CustomSplashScreen.hide();
内容的提问来源于stack exchange,提问作者carch
相关产品推荐
相关产品推荐

