- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // 1. init window self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; UIViewController *rootViewController = [UIViewController new]; // 2. backgroundView using LaunchScreen.xib UIView *backgroundView = [[[NSBundle mainBundle] loadNibNamed:@"LaunchScreen" owner:self options:nil] firstObject]; backgroundView.frame = self.window.bounds; // 3. ReactNative init NSURL *jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil]; RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"MyAwesomeApp" initialProperties:nil launchOptions:launchOptions]; // 4. rootView background clear, so our backgroundView can show until ReactNative has fully loaded rootView.backgroundColor = [UIColor clearColor]; // 5. set loadingView to the LaunchScreen.xib view too // explicitly set all frames UIView *launchScreenView = [[[NSBundle mainBundle] loadNibNamed:@"LaunchScreen" owner:self options:nil] firstObject]; rootView.frame = self.window.bounds; launchScreenView.frame = self.window.bounds; rootView.loadingView = launchScreenView; // 6. set the backgroundView as main view for the rootViewController (instead of the rootView) rootViewController.view = backgroundView; // 7. show self.window.rootViewController = rootViewController; [self.window makeKeyAndVisible]; // 8. after the window is visible, add the rootView as a subview to your backgroundView [backgroundView addSubview:rootView]; return YES; }