react-native-splash-screen
react-native-splash-screen copied to clipboard
Splash screen appears below JS content when using react native navigation
I started using [RNSplashScreen showSplash];
and it was working great, however, I didn't know that this method is blocking the thread with a while loop. This caused for some listeners and callbacks (for example, branch) to not be called only after hiding the splash screen.
After understanding this, I started using [RNSplashScreen showSplash:@"LaunchScreen" inRootView:rootView];
. However, it appeared for a second but when setting the rootScreen using RNN it disappeared because the JS content appears on top of it.
In order to fix it, I did this:
_window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
_window.backgroundColor = [UIColor clearColor];
_window.userInteractionEnabled = NO;
_window.rootViewController = rootViewController;
rootViewController.view.userInteractionEnabled = NO;
[RNSplashScreen showSplash:@"LaunchScreen" inRootView: rootViewController.view];
[_window setHidden:NO];
And now I see the splash screen until using hide();
.
Hi @Rotemy I'm trying your solution in RNN but it doesn't work. How did you get the rootViewController from RNN? Or is it something like this? UIViewController *rootViewController = [UIViewController new];
BTW the "LaunchScreen" in your solutions is the xib file right?
Yes I created a new ui view controller.
Here is my full code
// The only way to show the splash screen over the JS ui and without blocking the thread
rootViewController = [UIViewController new];
_window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
_window.backgroundColor = [UIColor clearColor];
_window.userInteractionEnabled = NO;
_window.rootViewController = rootViewController;
rootViewController.view.userInteractionEnabled = NO;
[RNSplashScreen showSplash:@"LaunchScreen" inRootView: rootViewController.view];
[_window setHidden:NO];
t = [NSTimer scheduledTimerWithTimeInterval: 2.0 target: self selector: @selector(onHideSplashScreen) userInfo: nil repeats:YES];
return YES;
- (void)onHideSplashScreen {
// I want to die for implementing this like that, but I don't have a choice right now :(
if (rootViewController.view.subviews.count == 0) {
[t invalidate];
t = nil;
[[[UIApplication sharedApplication] delegate] setWindow:mainWindow];
}
}
and the LaunchScreen
in this case is a xib that looks the same as the LunchScreen.storyboard
I set up in the settings of the project
Yes I created a new ui view controller.
Here is my full code
// The only way to show the splash screen over the JS ui and without blocking the thread rootViewController = [UIViewController new]; _window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; _window.backgroundColor = [UIColor clearColor]; _window.userInteractionEnabled = NO; _window.rootViewController = rootViewController; rootViewController.view.userInteractionEnabled = NO; [RNSplashScreen showSplash:@"LaunchScreen" inRootView: rootViewController.view]; [_window setHidden:NO]; t = [NSTimer scheduledTimerWithTimeInterval: 2.0 target: self selector: @selector(onHideSplashScreen) userInfo: nil repeats:YES]; return YES;
- (void)onHideSplashScreen { // I want to die for implementing this like that, but I don't have a choice right now :( if (rootViewController.view.subviews.count == 0) { [t invalidate]; t = nil; [[[UIApplication sharedApplication] delegate] setWindow:mainWindow]; } }
and the
LaunchScreen
in this case is a xib that looks the same as theLunchScreen.storyboard
I set up in the settings of the project
Thanks :) it works now. But I had to upgrade RNN to min v5.
Yes I created a new ui view controller. Here is my full code
// The only way to show the splash screen over the JS ui and without blocking the thread rootViewController = [UIViewController new]; _window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; _window.backgroundColor = [UIColor clearColor]; _window.userInteractionEnabled = NO; _window.rootViewController = rootViewController; rootViewController.view.userInteractionEnabled = NO; [RNSplashScreen showSplash:@"LaunchScreen" inRootView: rootViewController.view]; [_window setHidden:NO]; t = [NSTimer scheduledTimerWithTimeInterval: 2.0 target: self selector: @selector(onHideSplashScreen) userInfo: nil repeats:YES]; return YES;
- (void)onHideSplashScreen { // I want to die for implementing this like that, but I don't have a choice right now :( if (rootViewController.view.subviews.count == 0) { [t invalidate]; t = nil; [[[UIApplication sharedApplication] delegate] setWindow:mainWindow]; } }
and the
LaunchScreen
in this case is a xib that looks the same as theLunchScreen.storyboard
I set up in the settings of the projectThanks :) it works now. But I had to upgrade RNN to min v5.
happy I could help
I had no idea this was my issue until I stumbled upon this issue and tried out your solution, @Rotemy. I did not need the NSTimer
as you used, but switching away from [RNSplashScreen showSplash]
allowed me to control hiding the splash screen in JS as expected.
Seems like showSplash
has a conflict with some underlying API used by react-navigation and potentially other popular libraries. Would love to dig into it further but that's all I can assume at this point.
Can you guys share your AppDelegate.m
file? I can't seem to get it to work.
Can you guys share your
AppDelegate.m
file? I can't seem to get it to work.
Yes, same here. I would like to see the whole page of code to get mine to work also.
- (void)onHideSplashScreen { // I want to die for implementing this like that, but I don't have a choice right now :( if (rootViewController.view.subviews.count == 0) { [t invalidate]; t = nil; [[[UIApplication sharedApplication] delegate] setWindow:mainWindow]; } }
Where are you putting this at?
I have this problem here, but happens only on Android, anyone can help me?