diff --git a/README.md b/README.md
index dd3b1b39..8e27729e 100644
--- a/README.md
+++ b/README.md
@@ -23,7 +23,7 @@ A splash screen API for react-native which can programatically hide and show the
 ## Changes
 For React Native >= 0.47.0 use [v3.+](https://github.com/crazycodeboy/react-native-splash-screen/releases), for React Native < 0.47.0 use [v2.1.0](https://github.com/crazycodeboy/react-native-splash-screen/releases/tag/v1.0.9)
 
-## Examples  
+## Examples
 * [Examples](https://github.com/crazycodeboy/react-native-splash-screen/tree/master/examples)
 
 ![react-native-splash-screen-Android](https://raw.githubusercontent.com/crazycodeboy/react-native-splash-screen/v3.0.0/examples/Screenshots/react-native-splash-screen-Android.gif)
@@ -42,13 +42,13 @@ Run `npm i react-native-splash-screen --save`
 
 `react-native link react-native-splash-screen` or `rnpm link react-native-splash-screen`
 
-#### Manual installation  
+#### Manual installation
 
 **Android:**
 
 1. In your `android/settings.gradle` file, make the following additions:
 ```java
-include ':react-native-splash-screen'   
+include ':react-native-splash-screen'
 project(':react-native-splash-screen').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-splash-screen/android')
 ```
 
@@ -62,7 +62,7 @@ dependencies {
 }
 ```
 
-3. Update the MainApplication.java file to use `react-native-splash-screen` via the following changes:   
+3. Update the MainApplication.java file to use `react-native-splash-screen` via the following changes:
 
 ```java
 // react-native-splash-screen >= 0.3.1
@@ -135,11 +135,7 @@ Update `AppDelegate.m` with the following additions:
 
 
 ```obj-c
-#import "AppDelegate.h"
-
-#import <React/RCTBundleURLProvider.h>
-#import <React/RCTRootView.h>
-#import "RNSplashScreen.h"  // here
+#import "RNSplashScreen.h"
 
 @implementation AppDelegate
 
@@ -147,19 +143,21 @@ Update `AppDelegate.m` with the following additions:
 {
     // ...other code
 
-    [RNSplashScreen show];  // here
+    RNSplashScreen *launchScreen = [RNSplashScreen allocWithZone:nil];
+    [launchScreen show];
     return YES;
 }
 
 @end
-
 ```
 
-## Getting started  
+Create a LaunchScreen.storyboard and make sure the root view controller has a storyboard identifier of "LaunchScreen".
+
+## Getting started
 
 Import `react-native-splash-screen` in your JS file.
 
-`import SplashScreen from 'react-native-splash-screen'`    
+`import SplashScreen from 'react-native-splash-screen'`
 
 ### Android:
 
@@ -238,7 +236,7 @@ Change your `show` method to include your custom style:
 SplashScreen.show(this, R.style.SplashScreenTheme);
 ```
 
-### iOS    
+### iOS
 
 Customize your splash screen via `LaunchImage` or `LaunchScreen.xib`,
 
diff --git a/ios/RNSplashScreen.h b/ios/RNSplashScreen.h
index dab0939b..f030d20f 100644
--- a/ios/RNSplashScreen.h
+++ b/ios/RNSplashScreen.h
@@ -1,14 +1,9 @@
-/**
- * SplashScreen
- * 启动屏
- * from：http://www.devio.org
- * Author:CrazyCodeBoy
- * GitHub:https://github.com/crazycodeboy
- * Email:crazycodeboy@gmail.com
- */
 #import <React/RCTBridgeModule.h>
+#import <UIKit/UIKit.h>
 
-@interface RNSplashScreen : NSObject<RCTBridgeModule>
-+ (void)show;
-+ (void)hide;
+@interface RNSplashScreen : NSObject <RCTBridgeModule>
+@property(nonatomic, strong) UIViewController *launchScreen;
+- (void)show;
+- (void)hide;
+- (void)setup;
 @end
diff --git a/ios/RNSplashScreen.m b/ios/RNSplashScreen.m
index 69b45a63..dc171c7c 100644
--- a/ios/RNSplashScreen.m
+++ b/ios/RNSplashScreen.m
@@ -1,55 +1,75 @@
-/**
- * SplashScreen
- * 启动屏
- * from：http://www.devio.org
- * Author:CrazyCodeBoy
- * GitHub:https://github.com/crazycodeboy
- * Email:crazycodeboy@gmail.com
- */
-
 #import "RNSplashScreen.h"
 #import <React/RCTBridge.h>
 
-static bool waiting = true;
-static bool addedJsLoadErrorObserver = false;
-
 @implementation RNSplashScreen
-- (dispatch_queue_t)methodQueue{
-    return dispatch_get_main_queue();
-}
+
 RCT_EXPORT_MODULE(SplashScreen)
 
-+ (void)show {
-    if (!addedJsLoadErrorObserver) {
-        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(jsLoadError:) name:RCTJavaScriptDidFailToLoadNotification object:nil];
-        addedJsLoadErrorObserver = true;
-    }
++ (id)allocWithZone:(NSZone *)zone {
+  static RNSplashScreen *sharedInstance = nil;
+  static dispatch_once_t onceToken;
+  dispatch_once(&onceToken, ^{
+    sharedInstance = [super allocWithZone:zone];
 
-    while (waiting) {
-        NSDate* later = [NSDate dateWithTimeIntervalSinceNow:0.1];
-        [[NSRunLoop mainRunLoop] runUntilDate:later];
-    }
+    // Init.
+    [[NSNotificationCenter defaultCenter]
+        addObserver:sharedInstance
+           selector:@selector(jsLoadError:)
+               name:RCTJavaScriptDidFailToLoadNotification
+             object:nil];
+    sharedInstance.launchScreen =
+        [[UIStoryboard storyboardWithName:@"LaunchScreen"
+                                   bundle:[NSBundle mainBundle]]
+            instantiateViewControllerWithIdentifier:@"LaunchScreen"];
+  });
+  return sharedInstance;
 }
 
-+ (void)hide {
-    dispatch_async(dispatch_get_main_queue(),
-                   ^{
-                       waiting = false;
-                   });
+- (void)setup {
+  UIViewController *viewController =
+      [[[[UIApplication sharedApplication] delegate] window]
+          rootViewController];
+  [viewController.view addSubview:self.launchScreen.view];
 }
 
-+ (void) jsLoadError:(NSNotification*)notification
-{
-    // If there was an error loading javascript, hide the splash screen so it can be shown.  Otherwise the splash screen will remain forever, which is a hassle to debug.
-    [RNSplashScreen hide];
+RCT_EXPORT_METHOD(show) {
+  dispatch_async(dispatch_get_main_queue(), ^{
+    self.launchScreen.view.alpha = 0.0;
+    UIViewController *viewController =
+        [[[[UIApplication sharedApplication] delegate] window]
+            rootViewController];
+    [viewController.view addSubview:self.launchScreen.view];
+    [UIView animateWithDuration:0.5
+                          delay:0.0
+                        options:UIViewAnimationOptionCurveEaseIn
+                     animations:^{
+                       self.launchScreen.view.alpha = 1.0;
+                     }
+                     completion:^(BOOL finished){
+                     }];
+  });
 }
 
 RCT_EXPORT_METHOD(hide) {
-    [RNSplashScreen hide];
+  dispatch_async(dispatch_get_main_queue(), ^{
+    [UIView animateWithDuration:0.5
+        delay:0.0
+        options:UIViewAnimationOptionCurveEaseIn
+        animations:^{
+          self.launchScreen.view.alpha = 0;
+        }
+        completion:^(BOOL finished) {
+          [self.launchScreen.view removeFromSuperview];
+        }];
+  });
 }
 
-RCT_EXPORT_METHOD(show) {
-    [RNSplashScreen show];
+- (void)jsLoadError:(NSNotification *)notification {
+  // If there was an error loading javascript, hide the splash screen so it can
+  // be shown.
+  // Otherwise the splash screen will remain forever, which is a hassle to
+  // debug.
+  [self hide];
 }
 
 @end
