New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Initialization] Launch screen white flash #1402

Closed
alinz opened this Issue May 26, 2015 · 138 comments

Comments

Projects
None yet
@alinz
Contributor

alinz commented May 26, 2015

I just wondering if there is a good practice about LaunchScreen. The reason I'm asking this is, if one adds LaunchScreen, there is a white flash before react-native kicks in and load the app. Is there any way we can prevent this?

@brentvatne

This comment has been minimized.

Show comment
Hide comment
@brentvatne

brentvatne May 28, 2015

Collaborator

@alinz - this is fixed in the next release: tadeuzagallo@8d99226

Collaborator

brentvatne commented May 28, 2015

@alinz - this is fixed in the next release: tadeuzagallo@8d99226

@brentvatne brentvatne closed this May 28, 2015

@liubko

This comment has been minimized.

Show comment
Hide comment
Contributor

liubko commented May 31, 2015

@alinz

This comment has been minimized.

Show comment
Hide comment
@alinz

alinz May 31, 2015

Contributor

@liubko Yes, this is exactly what I want to get rid of. I haven't applied the patch yet but I will do it tonight.

Contributor

alinz commented May 31, 2015

@liubko Yes, this is exactly what I want to get rid of. I haven't applied the patch yet but I will do it tonight.

@oblador

This comment has been minimized.

Show comment
Hide comment
@oblador

oblador Jun 1, 2015

Contributor

@brentvatne: I don't see how that patch would fix this problem (if I'm blind/stupid please forgive :-). The problem is that there's a moment between when the app has launched and React is still working. Ideally the LaunchScreen would show until React is finished and fully rendered as it does in a "fully native" app.

Contributor

oblador commented Jun 1, 2015

@brentvatne: I don't see how that patch would fix this problem (if I'm blind/stupid please forgive :-). The problem is that there's a moment between when the app has launched and React is still working. Ideally the LaunchScreen would show until React is finished and fully rendered as it does in a "fully native" app.

@brentvatne

This comment has been minimized.

Show comment
Hide comment
@brentvatne

brentvatne Jun 1, 2015

Collaborator

@oblador - ah, this would allow you to transition more smoothly by having the same background colour as the launch screen in the "flicker" moment.

@vjeux - how do you get past this issue in FB apps? I noticed that F8, which if I understand correctly is 100% React Native, transitions directly from the launch screen to the app. cc @nicklockwood

Collaborator

brentvatne commented Jun 1, 2015

@oblador - ah, this would allow you to transition more smoothly by having the same background colour as the launch screen in the "flicker" moment.

@vjeux - how do you get past this issue in FB apps? I noticed that F8, which if I understand correctly is 100% React Native, transitions directly from the launch screen to the app. cc @nicklockwood

@brentvatne brentvatne reopened this Jun 1, 2015

@brentvatne brentvatne changed the title from Launch Screen white flash to [Initialization] Launch Screen white flash Jun 1, 2015

@brentvatne brentvatne changed the title from [Initialization] Launch Screen white flash to [Initialization] Launch screen white flash Jun 1, 2015

@nicklockwood

This comment has been minimized.

Show comment
Hide comment
@nicklockwood

nicklockwood Jun 1, 2015

Contributor

There's a (separate) fix for this issue too. Use the new loadingView property of RCTRootView, and set it to a full-screen UIImageView showing your launch image. The code might look something like this:

UIImageView *launchView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"MyLaunchImage"];
rootView.loadingView = launchView;

I've been experimenting with a way to automatically detect the launch image and make this completely automatic, but it's not really ready yet. If you're interested, it looks like this:

// TODO: support landscape orientation

// Get launch image
NSString *launchImageName = nil;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
  CGFloat height = MAX(RCTScreenSize().width, RCTScreenSize().height);
  if (height == 480) launchImageName = @"LaunchImage-700@2x.png"; // iPhone 4/4s
  else if (height == 568) launchImageName = @"LaunchImage-700-568h@2x.png"; // iPhone 5/5s
  else if (height == 667) launchImageName = @"LaunchImage-800-667h@2x.png"; // iPhone 6
  else if (height == 736) launchImageName = @"LaunchImage-800-Portrait-736h@3x.png"; // iPhone 6+
} else if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
  CGFloat scale = RCTScreenScale();
  if (scale == 1) launchImageName = @"LaunchImage-700-Portrait~ipad.png"; // iPad
  else if (scale == 2) launchImageName = @"LaunchImage-700-Portrait@2x~ipad.png"; // Retina iPad
}

// Create loading view
UIImage *image = [UIImage imageNamed:launchImageName];
if (image) {
  UIImageView *imageView = [[UIImageView alloc] initWithFrame:(CGRect){CGPointZero, RCTScreenSize()}];
  imageView.contentMode = UIViewContentModeBottom;
  imageView.image = image;
  rootView.loadingView = imageView;
}
Contributor

nicklockwood commented Jun 1, 2015

There's a (separate) fix for this issue too. Use the new loadingView property of RCTRootView, and set it to a full-screen UIImageView showing your launch image. The code might look something like this:

UIImageView *launchView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"MyLaunchImage"];
rootView.loadingView = launchView;

I've been experimenting with a way to automatically detect the launch image and make this completely automatic, but it's not really ready yet. If you're interested, it looks like this:

// TODO: support landscape orientation

// Get launch image
NSString *launchImageName = nil;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
  CGFloat height = MAX(RCTScreenSize().width, RCTScreenSize().height);
  if (height == 480) launchImageName = @"LaunchImage-700@2x.png"; // iPhone 4/4s
  else if (height == 568) launchImageName = @"LaunchImage-700-568h@2x.png"; // iPhone 5/5s
  else if (height == 667) launchImageName = @"LaunchImage-800-667h@2x.png"; // iPhone 6
  else if (height == 736) launchImageName = @"LaunchImage-800-Portrait-736h@3x.png"; // iPhone 6+
} else if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
  CGFloat scale = RCTScreenScale();
  if (scale == 1) launchImageName = @"LaunchImage-700-Portrait~ipad.png"; // iPad
  else if (scale == 2) launchImageName = @"LaunchImage-700-Portrait@2x~ipad.png"; // Retina iPad
}

// Create loading view
UIImage *image = [UIImage imageNamed:launchImageName];
if (image) {
  UIImageView *imageView = [[UIImageView alloc] initWithFrame:(CGRect){CGPointZero, RCTScreenSize()}];
  imageView.contentMode = UIViewContentModeBottom;
  imageView.image = image;
  rootView.loadingView = imageView;
}
@ide

This comment has been minimized.

Show comment
Hide comment
@ide

ide Jun 1, 2015

Collaborator

An easy solution to what @nicklockwood described is to load the launchscreen xib if you're on iOS 8+.

Collaborator

ide commented Jun 1, 2015

An easy solution to what @nicklockwood described is to load the launchscreen xib if you're on iOS 8+.

@alinz

This comment has been minimized.

Show comment
Hide comment
@alinz

alinz Jun 1, 2015

Contributor

@ide I am using launchscreen xib. I see my lauchscreen view at the launch time but before my app boots up, I see a white view (flash).

Contributor

alinz commented Jun 1, 2015

@ide I am using launchscreen xib. I see my lauchscreen view at the launch time but before my app boots up, I see a white view (flash).

@nicklockwood

This comment has been minimized.

Show comment
Hide comment
@nicklockwood

nicklockwood Jun 1, 2015

Contributor

@alinz, I believe @ide means to use your launchscreen xib to set the RCTRootView loadingView (which you'll still need to do manually). There is no automatic support for doing that (yet).

Contributor

nicklockwood commented Jun 1, 2015

@alinz, I believe @ide means to use your launchscreen xib to set the RCTRootView loadingView (which you'll still need to do manually). There is no automatic support for doing that (yet).

@nicklockwood

This comment has been minimized.

Show comment
Hide comment
@nicklockwood

nicklockwood Jun 1, 2015

Contributor

To clarify, iOS hides your launch screen at the point when React begins loading. To avoid seeing a blank screen, you'll need to extend the time that the launch screen is displayed by manually showing the same view as the RCTRootView's loadingView.

Contributor

nicklockwood commented Jun 1, 2015

To clarify, iOS hides your launch screen at the point when React begins loading. To avoid seeing a blank screen, you'll need to extend the time that the launch screen is displayed by manually showing the same view as the RCTRootView's loadingView.

@alinz

This comment has been minimized.

Show comment
Hide comment
@alinz

alinz Jun 1, 2015

Contributor

Thanks @nicklockwood for clarification. That was my bad. :)

Contributor

alinz commented Jun 1, 2015

Thanks @nicklockwood for clarification. That was my bad. :)

@dvine-multimedia

This comment has been minimized.

Show comment
Hide comment
@dvine-multimedia

dvine-multimedia Jun 8, 2015

Curtesy of http://stackoverflow.com/a/29115477/255765 I ended up with this:

for (NSString *imgName in allPngImageNames){
    // Find launch images
    if ([imgName containsString:@"LaunchImage"]){
      UIImage *img = [UIImage imageNamed:imgName]; //-- this is a launch image
      // Has image same scale and dimensions as our current device's screen?
      if (img.scale == [UIScreen mainScreen].scale && CGSizeEqualToSize(img.size, [UIScreen mainScreen].bounds.size)) {
        NSLog(@"Found launch image for current device %@", img.description);
        UIImageView *launchView = [[UIImageView alloc] initWithImage: img];
        rootView.loadingView = launchView;
      }
    }
  }

Seems to work.

Curtesy of http://stackoverflow.com/a/29115477/255765 I ended up with this:

for (NSString *imgName in allPngImageNames){
    // Find launch images
    if ([imgName containsString:@"LaunchImage"]){
      UIImage *img = [UIImage imageNamed:imgName]; //-- this is a launch image
      // Has image same scale and dimensions as our current device's screen?
      if (img.scale == [UIScreen mainScreen].scale && CGSizeEqualToSize(img.size, [UIScreen mainScreen].bounds.size)) {
        NSLog(@"Found launch image for current device %@", img.description);
        UIImageView *launchView = [[UIImageView alloc] initWithImage: img];
        rootView.loadingView = launchView;
      }
    }
  }

Seems to work.

@chirag04

This comment has been minimized.

Show comment
Hide comment
@chirag04

chirag04 Jun 16, 2015

Collaborator

+1 for a standard/documented way.

Collaborator

chirag04 commented Jun 16, 2015

+1 for a standard/documented way.

@nicklockwood

This comment has been minimized.

Show comment
Hide comment
@nicklockwood

nicklockwood Jun 16, 2015

Contributor

@dvine-multimedia does that work better than the code snippet I provided above?

Contributor

nicklockwood commented Jun 16, 2015

@dvine-multimedia does that work better than the code snippet I provided above?

@nicklockwood nicklockwood self-assigned this Jun 16, 2015

@myusuf3

This comment has been minimized.

Show comment
Hide comment
Contributor

myusuf3 commented Jun 21, 2015

@dvine-multimedia

This comment has been minimized.

Show comment
Hide comment
@dvine-multimedia

dvine-multimedia Jun 26, 2015

@nicklockwood Actually they do very much the same thing. When I started to look into this I probably didn't understand what to do with your snipped for pure lack of any xcode experience. When I finally got to the point where I understood what to do, I didn't realize, that you already had been there. Beside that, I personally find "my" solution a bit more readable. But that pure aesthetics.

@nicklockwood Actually they do very much the same thing. When I started to look into this I probably didn't understand what to do with your snipped for pure lack of any xcode experience. When I finally got to the point where I understood what to do, I didn't realize, that you already had been there. Beside that, I personally find "my" solution a bit more readable. But that pure aesthetics.

@chirag04

This comment has been minimized.

Show comment
Hide comment
@chirag04

chirag04 Jun 26, 2015

Collaborator

@nicklockwood I tried your code but i still see a white flash. I created a launch image to set as the loading view. launch image is same as the launchScreen.xib.

This is the only thing holding the release of our app. Really appreciate any help on this.

Collaborator

chirag04 commented Jun 26, 2015

@nicklockwood I tried your code but i still see a white flash. I created a launch image to set as the loading view. launch image is same as the launchScreen.xib.

This is the only thing holding the release of our app. Really appreciate any help on this.

@nicklockwood

This comment has been minimized.

Show comment
Hide comment
@nicklockwood

nicklockwood Jun 26, 2015

Contributor

Is the flash appearing after the launch image is hidden, or does the launch image fail to appear? (This may be hard to determine just by looking - change the launch image to something like a solid red rectangle temporarily to be sure).

Contributor

nicklockwood commented Jun 26, 2015

Is the flash appearing after the launch image is hidden, or does the launch image fail to appear? (This may be hard to determine just by looking - change the launch image to something like a solid red rectangle temporarily to be sure).

@chirag04

This comment has been minimized.

Show comment
Hide comment
@chirag04

chirag04 Jun 26, 2015

Collaborator

@nicklockwood I tried to change the color between xib file and the launchScreen Image. I was still seeing that flash.

My code looks like this:

 UIImageView *launchView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"launchScreen1"]];
 rootView.loadingView = launchView;

 rootView.loadingViewFadeDelay = 0.0;
 rootView.loadingViewFadeDuration = 0.15;

I removed the last two line loadingViewFadeDelay and duration now and it seems the problem is solved. I don't see any flash. Nice smooth transition.

Collaborator

chirag04 commented Jun 26, 2015

@nicklockwood I tried to change the color between xib file and the launchScreen Image. I was still seeing that flash.

My code looks like this:

 UIImageView *launchView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"launchScreen1"]];
 rootView.loadingView = launchView;

 rootView.loadingViewFadeDelay = 0.0;
 rootView.loadingViewFadeDuration = 0.15;

I removed the last two line loadingViewFadeDelay and duration now and it seems the problem is solved. I don't see any flash. Nice smooth transition.

@alinz

This comment has been minimized.

Show comment
Hide comment
@alinz

alinz Jun 26, 2015

Contributor

@chirag04 I just tried it with sample project and I didn't see the flash :(

here's what I did

  RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                      moduleName:@"whiteFlash"
                                                   launchOptions:launchOptions];

  //here's what I did
  UIImage *image = [UIImage imageNamed:@"LaunchImage"];
  if (image) {
    UIImageView *launchView = [[UIImageView alloc] initWithImage: image];
    launchView.contentMode = UIViewContentModeBottom;
    launchView.image = image;
    rootView.loadingView = launchView;
  }
  ///////////////////////////

  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  UIViewController *rootViewController = [[UIViewController alloc] init];
  rootViewController.view = rootView;
  self.window.rootViewController = rootViewController;
  [self.window makeKeyAndVisible];
  return YES;
Contributor

alinz commented Jun 26, 2015

@chirag04 I just tried it with sample project and I didn't see the flash :(

here's what I did

  RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                      moduleName:@"whiteFlash"
                                                   launchOptions:launchOptions];

  //here's what I did
  UIImage *image = [UIImage imageNamed:@"LaunchImage"];
  if (image) {
    UIImageView *launchView = [[UIImageView alloc] initWithImage: image];
    launchView.contentMode = UIViewContentModeBottom;
    launchView.image = image;
    rootView.loadingView = launchView;
  }
  ///////////////////////////

  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  UIViewController *rootViewController = [[UIViewController alloc] init];
  rootViewController.view = rootView;
  self.window.rootViewController = rootViewController;
  [self.window makeKeyAndVisible];
  return YES;
@chirag04

This comment has been minimized.

Show comment
Hide comment
@chirag04

chirag04 Jun 26, 2015

Collaborator

Ok. digging deeper it seems the flash maybe coz my app renders nothing until a value is loaded from asyncstore.

render() {
  if(!this.state.loaded) return (null);
  return <View ...../>;
}

I think the loadingView thinks that the js finished rendering and hides the loadingView. However js just finished rendering with that return null

@nicklockwood @alinz I'm just shooting in the air. may not be the actual reason. What do you guys think.

Also one thing i noticed is that if i set those loadingViewFadeDelay etc values to 0.30 or higher, the transition is very very smooth. the defaults are 0.25 which is also smooth.

Collaborator

chirag04 commented Jun 26, 2015

Ok. digging deeper it seems the flash maybe coz my app renders nothing until a value is loaded from asyncstore.

render() {
  if(!this.state.loaded) return (null);
  return <View ...../>;
}

I think the loadingView thinks that the js finished rendering and hides the loadingView. However js just finished rendering with that return null

@nicklockwood @alinz I'm just shooting in the air. may not be the actual reason. What do you guys think.

Also one thing i noticed is that if i set those loadingViewFadeDelay etc values to 0.30 or higher, the transition is very very smooth. the defaults are 0.25 which is also smooth.

@nicklockwood

This comment has been minimized.

Show comment
Hide comment
@nicklockwood

nicklockwood Jun 26, 2015

Contributor

The purpose of the loadingFadeDelay is precisely to cover the scenario where your app doesn't render anything up immediately, so you're using it correctly.

You might want to consider setting the loadingViewFadeDelay explicitly though, in case the default ever changes - and make sure you test on the slowest device you support, in case it takes longer to load.

Contributor

nicklockwood commented Jun 26, 2015

The purpose of the loadingFadeDelay is precisely to cover the scenario where your app doesn't render anything up immediately, so you're using it correctly.

You might want to consider setting the loadingViewFadeDelay explicitly though, in case the default ever changes - and make sure you test on the slowest device you support, in case it takes longer to load.

@alinz

This comment has been minimized.

Show comment
Hide comment
@alinz

alinz Jun 26, 2015

Contributor

I like @nicklockwood solution but you have to consider network latency which can not be predict.

One other solution is, set component state to some sort of default value to tell your component to display some sort of loading dialog.

Contributor

alinz commented Jun 26, 2015

I like @nicklockwood solution but you have to consider network latency which can not be predict.

One other solution is, set component state to some sort of default value to tell your component to display some sort of loading dialog.

@chirag04

This comment has been minimized.

Show comment
Hide comment
@chirag04

chirag04 Jun 26, 2015

Collaborator

Cool. I think i have the solution.

What do you guys think about having 3 components all being the same.

1) launchScreen.xib
2) loadingView
3) return null in render to actually render a view which is like loadingView and launchScreen.xib?

Not sure how point 3 will scale on different devices though. Would you guys even suggest that?

Collaborator

chirag04 commented Jun 26, 2015

Cool. I think i have the solution.

What do you guys think about having 3 components all being the same.

1) launchScreen.xib
2) loadingView
3) return null in render to actually render a view which is like loadingView and launchScreen.xib?

Not sure how point 3 will scale on different devices though. Would you guys even suggest that?

@nicklockwood

This comment has been minimized.

Show comment
Hide comment
@nicklockwood

nicklockwood Jun 26, 2015

Contributor

If the startup time depends on network then tes, I'd definitely advocate drawing an "empty" view immediately instead of hoping it downloads faster than fade delay.

Contributor

nicklockwood commented Jun 26, 2015

If the startup time depends on network then tes, I'd definitely advocate drawing an "empty" view immediately instead of hoping it downloads faster than fade delay.

@chirag04

This comment has been minimized.

Show comment
Hide comment
@chirag04

chirag04 Jun 26, 2015

Collaborator

depends on asyncstorage. no network

Collaborator

chirag04 commented Jun 26, 2015

depends on asyncstorage. no network

@alinz

This comment has been minimized.

Show comment
Hide comment
@alinz

alinz Jun 28, 2015

Contributor

Whether you are depending on network or not, I don't really like using time base display. There is no way you can 100% guarantee that the time you set is accurate. You should always display something to user to indicate that something is happening but it is not ready to display. This is just a suggestion.

Contributor

alinz commented Jun 28, 2015

Whether you are depending on network or not, I don't really like using time base display. There is no way you can 100% guarantee that the time you set is accurate. You should always display something to user to indicate that something is happening but it is not ready to display. This is just a suggestion.

@nicklockwood

This comment has been minimized.

Show comment
Hide comment
@nicklockwood

nicklockwood Jun 28, 2015

Contributor

Agreed. The purpose of the loadingView, like the standard iOS loading image, is just to to cover until your app is ready to display something, even if all the app is ready to display is a loading spinner.

That said, the reason I made it a view instead of an image is so you can make it non-static. You could add a UIActivityIndicatorView to the loadingView if you want.

Contributor

nicklockwood commented Jun 28, 2015

Agreed. The purpose of the loadingView, like the standard iOS loading image, is just to to cover until your app is ready to display something, even if all the app is ready to display is a loading spinner.

That said, the reason I made it a view instead of an image is so you can make it non-static. You could add a UIActivityIndicatorView to the loadingView if you want.

@Intellicode

This comment has been minimized.

Show comment
Hide comment
@Intellicode

Intellicode Jul 27, 2015

Contributor

How can the launch image be positioned? I've tried adjusting the frame origin, but it always positions it in the center no matter what origin I used. I have a small top bar image that I want to position top and stretched from left to right.

This is what I have:

  UIImageView *launchView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"LaunchImage"]];
  CGRect frame = launchView.frame;
  frame.origin.x = 0;
  frame.origin.y = 0;
  launchView.frame = frame;
  rootView.loadingView = launchView;
  rootView.loadingViewFadeDelay = 0.0;
  rootView.loadingViewFadeDuration = 0.0;
Contributor

Intellicode commented Jul 27, 2015

How can the launch image be positioned? I've tried adjusting the frame origin, but it always positions it in the center no matter what origin I used. I have a small top bar image that I want to position top and stretched from left to right.

This is what I have:

  UIImageView *launchView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"LaunchImage"]];
  CGRect frame = launchView.frame;
  frame.origin.x = 0;
  frame.origin.y = 0;
  launchView.frame = frame;
  rootView.loadingView = launchView;
  rootView.loadingViewFadeDelay = 0.0;
  rootView.loadingViewFadeDuration = 0.0;
@nicklockwood

This comment has been minimized.

Show comment
Hide comment
@nicklockwood

nicklockwood Jul 27, 2015

Contributor

It's not a launch image, it's a launch view, so you can position your imageView inside another container view and use the container as the launch view:

UIView *launchView = [[UIView alloc] init];
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"LaunchImage"]];
imageView.frame = CGRectMake(whatever);
[launchView addSubview:imageView];
...
Contributor

nicklockwood commented Jul 27, 2015

It's not a launch image, it's a launch view, so you can position your imageView inside another container view and use the container as the launch view:

UIView *launchView = [[UIView alloc] init];
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"LaunchImage"]];
imageView.frame = CGRectMake(whatever);
[launchView addSubview:imageView];
...
@Intellicode

This comment has been minimized.

Show comment
Hide comment
@Intellicode

Intellicode Jul 28, 2015

Contributor

True, I suppose I could make the wrapper fill the screen space and position the image at the top. The wrapper will be automatically positioned in the center by the RootView it seems

_loadingView.center = (CGPoint){
.

Contributor

Intellicode commented Jul 28, 2015

True, I suppose I could make the wrapper fill the screen space and position the image at the top. The wrapper will be automatically positioned in the center by the RootView it seems

_loadingView.center = (CGPoint){
.

@nicklockwood

This comment has been minimized.

Show comment
Hide comment
Contributor

nicklockwood commented Jul 28, 2015

@chirag04

This comment has been minimized.

Show comment
Hide comment
@chirag04

chirag04 Jul 29, 2015

Collaborator

Just broke my app in production on iphone 4s using @dvine-multimedia's code. fix is to just put a break in the if.

Collaborator

chirag04 commented Jul 29, 2015

Just broke my app in production on iphone 4s using @dvine-multimedia's code. fix is to just put a break in the if.

@chirag04

This comment has been minimized.

Show comment
Hide comment
@chirag04

chirag04 Jul 30, 2015

Collaborator

One more crash because containsString is not available on ios 7.

@nicklockwood wondering if loading view will automatically pick the best resolution possible?

Collaborator

chirag04 commented Jul 30, 2015

One more crash because containsString is not available on ios 7.

@nicklockwood wondering if loading view will automatically pick the best resolution possible?

@ajoshdee

This comment has been minimized.

Show comment
Hide comment
@ajoshdee

ajoshdee May 30, 2016

UIView *loading = [[[NSBundle mainBundle] loadNibNamed:@"LaunchScreen" owner:self options:nil] objectAtIndex:0];
rootView.loadingView = loading;

the loading UI view, it doesn't seem to resize, its suppose to be the same as my splash screen which is my LaunchScreen.xib

UIView *loading = [[[NSBundle mainBundle] loadNibNamed:@"LaunchScreen" owner:self options:nil] objectAtIndex:0];
rootView.loadingView = loading;

the loading UI view, it doesn't seem to resize, its suppose to be the same as my splash screen which is my LaunchScreen.xib

@ajoshdee

This comment has been minimized.

Show comment
Hide comment
@ajoshdee

ajoshdee May 30, 2016

I'm using size classes and constraints BTW

I'm using size classes and constraints BTW

@nicklockwood

This comment has been minimized.

Show comment
Hide comment
@nicklockwood

nicklockwood May 30, 2016

Contributor

@akoshdee that's correct - you'll need to set the view size explicitly to the match the screen size. Using

loading.frame = [UIScreen mainScreen].bounds;
Contributor

nicklockwood commented May 30, 2016

@akoshdee that's correct - you'll need to set the view size explicitly to the match the screen size. Using

loading.frame = [UIScreen mainScreen].bounds;
@ajoshdee

This comment has been minimized.

Show comment
Hide comment
@ajoshdee

ajoshdee May 30, 2016

already changed the frame but still doesn't work

already changed the frame but still doesn't work

@py110

This comment has been minimized.

Show comment
Hide comment
@py110

py110 May 31, 2016

any solution for android?

py110 commented May 31, 2016

any solution for android?

@ryankask

This comment has been minimized.

Show comment
Hide comment
@ryankask

ryankask May 31, 2016

Contributor

@ajoshdee The loadingView.frame = [UIScreen mainScreen].bounds; assignment didn't work for me but this did: loadingView.frame = self.window.bounds;

This is what I am using:

NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:@"LaunchScreen" owner:self options:nil];
UIImageView *loadingView = [nibObjects objectAtIndex:0];
loadingView.frame = self.window.bounds;
rootView.loadingView = loadingView;
Contributor

ryankask commented May 31, 2016

@ajoshdee The loadingView.frame = [UIScreen mainScreen].bounds; assignment didn't work for me but this did: loadingView.frame = self.window.bounds;

This is what I am using:

NSArray *nibObjects = [[NSBundle mainBundle] loadNibNamed:@"LaunchScreen" owner:self options:nil];
UIImageView *loadingView = [nibObjects objectAtIndex:0];
loadingView.frame = self.window.bounds;
rootView.loadingView = loadingView;
@bashtan

This comment has been minimized.

Show comment
Hide comment
@bashtan

bashtan Jun 8, 2016

Hello! I set color to react view:
rootViewController.view.backgroundColor = [UIColor blackColor];

bashtan commented Jun 8, 2016

Hello! I set color to react view:
rootViewController.view.backgroundColor = [UIColor blackColor];

@mehcode

This comment has been minimized.

Show comment
Hide comment
@mehcode

mehcode Jun 22, 2016

Contributor

@py110 @ajwhite

Android solution is stupidly simple to the point of being annoyed at myself for how long it took to figure it out.

It involves a 3-stage splash screen.

mehcode/rn-splash-screen#1

Contributor

mehcode commented Jun 22, 2016

@py110 @ajwhite

Android solution is stupidly simple to the point of being annoyed at myself for how long it took to figure it out.

It involves a 3-stage splash screen.

mehcode/rn-splash-screen#1

@ajwhite

This comment has been minimized.

Show comment
Hide comment
@ajwhite

ajwhite Jun 22, 2016

Contributor

I had a similar implementation @mehcode -- I like what you've got here though. I've been looking for a way to access the RN Instance manager, did not see that there was a getReactNativeHost() call, very good to know.

I had done the following, (not happy about it)

  1. SplashActivity started when app opens
  2. Immediately opens the MainActivity and finish()
  3. MainActivity starts the SplashActivity with a flag indicating it's in "foreground mode" as soon as it starts to show the splash above the MainActivity. After a short period of time, the SplashActivity closes itself revealing the app.
Contributor

ajwhite commented Jun 22, 2016

I had a similar implementation @mehcode -- I like what you've got here though. I've been looking for a way to access the RN Instance manager, did not see that there was a getReactNativeHost() call, very good to know.

I had done the following, (not happy about it)

  1. SplashActivity started when app opens
  2. Immediately opens the MainActivity and finish()
  3. MainActivity starts the SplashActivity with a flag indicating it's in "foreground mode" as soon as it starts to show the splash above the MainActivity. After a short period of time, the SplashActivity closes itself revealing the app.
@mehcode

This comment has been minimized.

Show comment
Hide comment
@mehcode

mehcode Jun 22, 2016

Contributor

@ajwhite

Thanks. The effect is very smooth.

In my current projects I quite literally have ReactActivity copied into my codebase and have made the mReactInstanceMangager protected instead of private.

In react-native 0.29 (should have said in the comment) the react native team gave us a public method getReactNativeHost() to get into it.

Contributor

mehcode commented Jun 22, 2016

@ajwhite

Thanks. The effect is very smooth.

In my current projects I quite literally have ReactActivity copied into my codebase and have made the mReactInstanceMangager protected instead of private.

In react-native 0.29 (should have said in the comment) the react native team gave us a public method getReactNativeHost() to get into it.

@ajwhite

This comment has been minimized.

Show comment
Hide comment
@ajwhite

ajwhite Jun 23, 2016

Contributor

That ReactNativeHost container is a brilliant move. This is exactly the problem I ran into -- not being able to hook into the lifecycle from the MainActivity.

Ref for the interested: 49f20f4#diff-1346852de0c7f8466a36d42de50ec808R20

Contributor

ajwhite commented Jun 23, 2016

That ReactNativeHost container is a brilliant move. This is exactly the problem I ran into -- not being able to hook into the lifecycle from the MainActivity.

Ref for the interested: 49f20f4#diff-1346852de0c7f8466a36d42de50ec808R20

@davidianbonner

This comment has been minimized.

Show comment
Hide comment
@davidianbonner

davidianbonner Jun 23, 2016

To add onto this...

A solution I found was to assign the rootView a background color but use [UIColor colorWithPatternImage:img].

This doesn't require any delays to ensure it stays visible until fully loaded.

A full snippet (and using the tip provided by @dvine-multimedia) that will find the desired LaunchImage for the device is below:

NSArray *allPngImageNames = [[NSBundle mainBundle] pathsForResourcesOfType:@"png" inDirectory:nil];
  for (NSString *imgName in allPngImageNames){
    if ([imgName containsString:@"LaunchImage"]){
      UIImage *img = [UIImage imageNamed:imgName];

      if (img.scale == [UIScreen mainScreen].scale && CGSizeEqualToSize(img.size, [UIScreen mainScreen].bounds.size)) {
        rootView.backgroundColor = [UIColor colorWithPatternImage:img];
      }
  }
}

The LaunchImage now stays visible until the react-native bundle has fully loaded.

To add onto this...

A solution I found was to assign the rootView a background color but use [UIColor colorWithPatternImage:img].

This doesn't require any delays to ensure it stays visible until fully loaded.

A full snippet (and using the tip provided by @dvine-multimedia) that will find the desired LaunchImage for the device is below:

NSArray *allPngImageNames = [[NSBundle mainBundle] pathsForResourcesOfType:@"png" inDirectory:nil];
  for (NSString *imgName in allPngImageNames){
    if ([imgName containsString:@"LaunchImage"]){
      UIImage *img = [UIImage imageNamed:imgName];

      if (img.scale == [UIScreen mainScreen].scale && CGSizeEqualToSize(img.size, [UIScreen mainScreen].bounds.size)) {
        rootView.backgroundColor = [UIColor colorWithPatternImage:img];
      }
  }
}

The LaunchImage now stays visible until the react-native bundle has fully loaded.

@sercanov

This comment has been minimized.

Show comment
Hide comment
@sercanov

sercanov Jun 27, 2016

Contributor

I've tried nearly every code block in this conversation with no chance but this one worked perfectly.
Thanks @dbonner1987 !

Contributor

sercanov commented Jun 27, 2016

I've tried nearly every code block in this conversation with no chance but this one worked perfectly.
Thanks @dbonner1987 !

@pareekkhushboo77

This comment has been minimized.

Show comment
Hide comment
@pareekkhushboo77

pareekkhushboo77 Aug 10, 2016

any solution for android?

any solution for android?

@mehcode

This comment has been minimized.

Show comment
Hide comment
@mehcode

mehcode Aug 10, 2016

Contributor

@pareekkhushboo77 https://github.com/mehcode/rn-splash-screen/blob/master/docs/android.md


@sercanov @dbonner1987 This also uses the approach mentioned above for iOS to do the javascript launch screen.

Contributor

mehcode commented Aug 10, 2016

@pareekkhushboo77 https://github.com/mehcode/rn-splash-screen/blob/master/docs/android.md


@sercanov @dbonner1987 This also uses the approach mentioned above for iOS to do the javascript launch screen.

@MiLeung

This comment has been minimized.

Show comment
Hide comment
@MiLeung

MiLeung Aug 13, 2016

@arnemart Thanks, still kinda works in RN 0.30.0. I had to delete my app and reinstall it. It had the white flash the first time, but none after that.

MiLeung commented Aug 13, 2016

@arnemart Thanks, still kinda works in RN 0.30.0. I had to delete my app and reinstall it. It had the white flash the first time, but none after that.

@UKDeveloper99

This comment has been minimized.

Show comment
Hide comment
@UKDeveloper99

UKDeveloper99 Aug 30, 2016

@nicklockwood Is there some sort of callback I can use to know when the actual javascript is loaded. The reason for this being, when my app is navigating between pages there is some transparency where rootView.backgroundColor is visible in the background of the view. I also get a similar problem with the Drawer plugin I'm using during the drawer open transition.
So I would like to do something like:

  • Set the rootView background color to the launcher image, using @dbonner1987 's approach above during the loading process.
  • When the javascript has finished loading and the first navigation route starts (or something along those lines)
  • Set the rootView background color back to white.

So I basically need a callback to know when the the loading is done.

@nicklockwood Is there some sort of callback I can use to know when the actual javascript is loaded. The reason for this being, when my app is navigating between pages there is some transparency where rootView.backgroundColor is visible in the background of the view. I also get a similar problem with the Drawer plugin I'm using during the drawer open transition.
So I would like to do something like:

  • Set the rootView background color to the launcher image, using @dbonner1987 's approach above during the loading process.
  • When the javascript has finished loading and the first navigation route starts (or something along those lines)
  • Set the rootView background color back to white.

So I basically need a callback to know when the the loading is done.

@mehcode

This comment has been minimized.

Show comment
Hide comment
@mehcode

mehcode Aug 30, 2016

Contributor

@UKDeveloper99 Please refer to the documentation I have linked above a couple times. There is such a callback available.

https://github.com/mehcode/rn-splash-screen/blob/master/docs/android.md

Contributor

mehcode commented Aug 30, 2016

@UKDeveloper99 Please refer to the documentation I have linked above a couple times. There is such a callback available.

https://github.com/mehcode/rn-splash-screen/blob/master/docs/android.md

@UKDeveloper99

This comment has been minimized.

Show comment
Hide comment
@UKDeveloper99

UKDeveloper99 Aug 31, 2016

@mehcode that's perfect thanks!!

@mehcode that's perfect thanks!!

@comountainclimber

This comment has been minimized.

Show comment
Hide comment
@comountainclimber

comountainclimber Oct 13, 2016

Anyone have suggestions for how to implement a LaunchScreen.storyboard that turns off once bundle has loaded? Currently it displays for a fixed amount of time then I see white screen and then application loads RN 34.1 xcode 8

comountainclimber commented Oct 13, 2016

Anyone have suggestions for how to implement a LaunchScreen.storyboard that turns off once bundle has loaded? Currently it displays for a fixed amount of time then I see white screen and then application loads RN 34.1 xcode 8

@jakecraige

This comment has been minimized.

Show comment
Hide comment
@jakecraige

jakecraige Dec 28, 2016

@ajoshdee I had similar issues where the view ended up being much larger than the screen. Not sure if it's related but I was using AutoLayout in my LaunchScreen.xib.

I needed to also set

launchScreenView.autoresizingMask = UIViewAutoresizingNone;

To get it to size properly.

So #1402 (comment) with that added line above

@ajoshdee I had similar issues where the view ended up being much larger than the screen. Not sure if it's related but I was using AutoLayout in my LaunchScreen.xib.

I needed to also set

launchScreenView.autoresizingMask = UIViewAutoresizingNone;

To get it to size properly.

So #1402 (comment) with that added line above

@Fantasim

This comment has been minimized.

Show comment
Hide comment
@Fantasim

Fantasim Jan 26, 2017

You can also update launch color in replace this line in appdelegate.m :

rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];

by this line :
rootView.backgroundColor = [[UIColor alloc] initWithRed:0.94 green:0.90 blue:0.89 alpha:1.0];

and find color you want with this website

Fantasim commented Jan 26, 2017

You can also update launch color in replace this line in appdelegate.m :

rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];

by this line :
rootView.backgroundColor = [[UIColor alloc] initWithRed:0.94 green:0.90 blue:0.89 alpha:1.0];

and find color you want with this website

@AdrianZghibarta

This comment has been minimized.

Show comment
Hide comment
@AdrianZghibarta

AdrianZghibarta Aug 8, 2017

Did someone managed the resolve this on Android ?

Did someone managed the resolve this on Android ?

@neomib

This comment has been minimized.

Show comment
Hide comment
@neomib

neomib Oct 25, 2017

Here is a solution for both ios and android: https://github.com/mehcode/rn-splash-screen.
I hid the splash screen in the render function of my app.tsx (the entry point) and showed the same image until all of my https requests were done.

My code:

public render()
   {
       SplashScreen.hide();

      //after everything has finished loading - show my app.
      if (this.state.isFinishedloading) 
       {
           return (
               <this.navigator screenProps={{ ...providers }} />
           );
       }

     // Until then show the same image as the splash screen with an ActivityIndicator.
       return (
          <View style={{ flex: 1 }}>
             <Image style={styles.image} source={require('../assets/img/splash.png')} >
               <ActivityIndicator  style={styles.indicator} color="#fff"></ActivityIndicator>
             </Image>
          </View>
       );

   }

neomib commented Oct 25, 2017

Here is a solution for both ios and android: https://github.com/mehcode/rn-splash-screen.
I hid the splash screen in the render function of my app.tsx (the entry point) and showed the same image until all of my https requests were done.

My code:

public render()
   {
       SplashScreen.hide();

      //after everything has finished loading - show my app.
      if (this.state.isFinishedloading) 
       {
           return (
               <this.navigator screenProps={{ ...providers }} />
           );
       }

     // Until then show the same image as the splash screen with an ActivityIndicator.
       return (
          <View style={{ flex: 1 }}>
             <Image style={styles.image} source={require('../assets/img/splash.png')} >
               <ActivityIndicator  style={styles.indicator} color="#fff"></ActivityIndicator>
             </Image>
          </View>
       );

   }
@JakeRawr

This comment has been minimized.

Show comment
Hide comment
@JakeRawr

JakeRawr Dec 12, 2017

Contributor

Is there any solution for this if I am using storyboard for splash screen? I don't have my launch screen images for each dimension anymore.

Contributor

JakeRawr commented Dec 12, 2017

Is there any solution for this if I am using storyboard for splash screen? I don't have my launch screen images for each dimension anymore.

@a3diti

This comment has been minimized.

Show comment
Hide comment
@a3diti

a3diti Jan 8, 2018

In react native for iOS inside AppDelegate.m change the following line by writing your RGB color codes accordingly:

rootView.backgroundColor = [[UIColor alloc] initWithRed:52.0f/255.0f green:73.0f/255.0f blue:94.0f/255.0f alpha:1];

For RED change the number 52
For GREEN change the number 73
For BLUE change the number 94

Note: I'm using react native v0.51.0

a3diti commented Jan 8, 2018

In react native for iOS inside AppDelegate.m change the following line by writing your RGB color codes accordingly:

rootView.backgroundColor = [[UIColor alloc] initWithRed:52.0f/255.0f green:73.0f/255.0f blue:94.0f/255.0f alpha:1];

For RED change the number 52
For GREEN change the number 73
For BLUE change the number 94

Note: I'm using react native v0.51.0

timothyej added a commit to blockfirm/bithodl-app that referenced this issue Jan 21, 2018

Show the Launch Screen until React has finished loading
The Launch Screen is only shown until the app has loaded, not until
React has loaded. This results in a white flash between the Launch
Screen and the initial view of the app. This commit fixes that by
showing the Launch Screen until React also has finished loading.

The solution was found here:
facebook/react-native#1402 (comment)
@otoinsa

This comment has been minimized.

Show comment
Hide comment
@otoinsa

otoinsa Jan 31, 2018

Is there still no solution for Android?

otoinsa commented Jan 31, 2018

Is there still no solution for Android?

@BasitAli

This comment has been minimized.

Show comment
Hide comment
@BasitAli

BasitAli Jan 31, 2018

@otoinsa see the above answer #1402 (comment) by @neomib. There are some other splash screen libraries that work just as well for e.g. https://github.com/crazycodeboy/react-native-splash-screen.

@otoinsa see the above answer #1402 (comment) by @neomib. There are some other splash screen libraries that work just as well for e.g. https://github.com/crazycodeboy/react-native-splash-screen.

@rimzici

This comment has been minimized.

Show comment
Hide comment
@rimzici

rimzici Mar 30, 2018

Any suggestion on storyboard used as LaunchScreen ?

My approach was like this (but the app crashes at launch)

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
	NSURL *jsCodeLocation;
	[Fabric with:@[[Crashlytics class]]];

	jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];

	RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
								moduleName:@"MyApp"
								initialProperties:nil
								launchOptions:launchOptions];
	rootView.backgroundColor = [UIColor clearColor];
 
	self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  
//  UIViewController *rootViewController = [UIViewController new];

  UIStoryboard *storyboard = self.window.rootViewController.storyboard;
  UIViewController *rootViewController = [storyboard instantiateViewControllerWithIdentifier:@"the_storyboard_id"];
  
	rootViewController.view = rootView;
	self.window.rootViewController = rootViewController;
	[self.window makeKeyAndVisible];
	return YES;
}

the app crashes with the following error:

2018-03-30 11:21:04.995601+0530 MyApp[6119:101967] Running application MyApp ({
    initialProps =     {
    };
    rootTag = 1;
})
2018-03-30 11:21:05.014109+0530 MyApp[6119:101967] *** Assertion failure in -[UIApplication _runWithMainScene:transitionContext:completion:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3698.33.6/UIApplication.m:3529
2018-03-30 11:21:05.090174+0530 MyApp[6119:101967] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Application windows are expected to have a root view controller at the end of application launch'
*** First throw call stack:
(
	0   CoreFoundation                      0x000000011170f12b __exceptionPreprocess + 171
	1   libobjc.A.dylib                     0x0000000110001f41 objc_exception_throw + 48
	2   CoreFoundation                      0x00000001117142f2 +[NSException raise:format:arguments:] + 98
	3   Foundation                          0x000000010faa2d69 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 193
	4   UIKit                               0x000000010d838051 -[UIApplication _runWithMainScene:transitionContext:completion:] + 3102
	5   UIKit                               0x000000010dc016f8 __111-[__UICanvasLifecycleMonitor_Compatability _scheduleFirstCommitForScene:transition:firstActivation:completion:]_block_invoke + 924
	6   UIKit                               0x000000010dfd74c8 +[_UICanvas _enqueuePostSettingUpdateTransactionBlock:] + 153
	7   UIKit                               0x000000010dc012f1 -

Thanks.

rimzici commented Mar 30, 2018

Any suggestion on storyboard used as LaunchScreen ?

My approach was like this (but the app crashes at launch)

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
	NSURL *jsCodeLocation;
	[Fabric with:@[[Crashlytics class]]];

	jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];

	RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
								moduleName:@"MyApp"
								initialProperties:nil
								launchOptions:launchOptions];
	rootView.backgroundColor = [UIColor clearColor];
 
	self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  
//  UIViewController *rootViewController = [UIViewController new];

  UIStoryboard *storyboard = self.window.rootViewController.storyboard;
  UIViewController *rootViewController = [storyboard instantiateViewControllerWithIdentifier:@"the_storyboard_id"];
  
	rootViewController.view = rootView;
	self.window.rootViewController = rootViewController;
	[self.window makeKeyAndVisible];
	return YES;
}

the app crashes with the following error:

2018-03-30 11:21:04.995601+0530 MyApp[6119:101967] Running application MyApp ({
    initialProps =     {
    };
    rootTag = 1;
})
2018-03-30 11:21:05.014109+0530 MyApp[6119:101967] *** Assertion failure in -[UIApplication _runWithMainScene:transitionContext:completion:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3698.33.6/UIApplication.m:3529
2018-03-30 11:21:05.090174+0530 MyApp[6119:101967] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Application windows are expected to have a root view controller at the end of application launch'
*** First throw call stack:
(
	0   CoreFoundation                      0x000000011170f12b __exceptionPreprocess + 171
	1   libobjc.A.dylib                     0x0000000110001f41 objc_exception_throw + 48
	2   CoreFoundation                      0x00000001117142f2 +[NSException raise:format:arguments:] + 98
	3   Foundation                          0x000000010faa2d69 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 193
	4   UIKit                               0x000000010d838051 -[UIApplication _runWithMainScene:transitionContext:completion:] + 3102
	5   UIKit                               0x000000010dc016f8 __111-[__UICanvasLifecycleMonitor_Compatability _scheduleFirstCommitForScene:transition:firstActivation:completion:]_block_invoke + 924
	6   UIKit                               0x000000010dfd74c8 +[_UICanvas _enqueuePostSettingUpdateTransactionBlock:] + 153
	7   UIKit                               0x000000010dc012f1 -

Thanks.

@rimzici

This comment has been minimized.

Show comment
Hide comment
@rimzici

rimzici Mar 30, 2018

replaced

UIStoryboard *storyboard = self.window.rootViewController.storyboard;

with

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"LaunchScreen" bundle:nil];

now the app starts but I get black background.

rimzici commented Mar 30, 2018

replaced

UIStoryboard *storyboard = self.window.rootViewController.storyboard;

with

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"LaunchScreen" bundle:nil];

now the app starts but I get black background.

@hajjiTarik

This comment has been minimized.

Show comment
Hide comment

timothyej added a commit to blockfirm/payla-app that referenced this issue Apr 7, 2018

Show the Launch Screen until React has finished loading
The Launch Screen is only shown until the app has loaded, not until
React has loaded. This results in a white flash between the Launch
Screen and the initial view of the app. This commit fixes that by
showing the Launch Screen until React also has finished loading.

The solution was found here:
facebook/react-native#1402 (comment)

@leonskim leonskim referenced this issue May 23, 2018

Merged

Splash screen #24

@facebook facebook locked as resolved and limited conversation to collaborators Jul 22, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.