You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 04:00:35