├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── SplashScreen.js ├── android ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── com │ └── reactnativecomponent │ └── splashscreen │ ├── RCTSplashScreen.java │ ├── RCTSplashScreenModule.java │ └── RCTSplashScreenPackage.java ├── ios ├── RCTSplashScreen │ ├── RCTSplashScreen.xcodeproj │ │ ├── project.pbxproj │ │ └── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ └── RCTSplashScreen │ │ ├── RCTSplashScreen.h │ │ └── RCTSplashScreen.m └── SplashScreenResource │ ├── LaunchScreen.xib │ └── splash.png ├── note.md └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | *.[aod] 2 | *.DS_Store 3 | .DS_Store 4 | *Thumbs.db 5 | *.iml 6 | .gradle 7 | .idea 8 | node_modules 9 | npm-debug.log 10 | /android/build 11 | /ios/**/*xcuserdata* 12 | /ios/**/*xcshareddata* -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | *.[aod] 2 | *.DS_Store 3 | .DS_Store 4 | *Thumbs.db 5 | *.iml 6 | .gradle 7 | .idea 8 | node_modules 9 | npm-debug.log 10 | /android/build 11 | /ios/**/*xcuserdata* 12 | /ios/**/*xcshareddata* -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-native-smart-splash-screen 2 | 3 | [![npm](https://img.shields.io/npm/v/react-native-smart-splash-screen.svg)](https://www.npmjs.com/package/react-native-smart-splash-screen) 4 | [![npm](https://img.shields.io/npm/dm/react-native-smart-splash-screen.svg)](https://www.npmjs.com/package/react-native-smart-splash-screen) 5 | [![npm](https://img.shields.io/npm/dt/react-native-smart-splash-screen.svg)](https://www.npmjs.com/package/react-native-smart-splash-screen) 6 | [![npm](https://img.shields.io/npm/l/react-native-smart-splash-screen.svg)](https://github.com/react-native-component/react-native-smart-splash-screen/blob/master/LICENSE) 7 | 8 | A smart splash screen for React Native apps, written in JS, oc and java for cross-platform support. 9 | It works on iOS and Android. 10 | 11 | ## Preview 12 | 13 | ![react-native-smart-splash-screen-ios-preview][1] 14 | ![react-native-smart-splash-screen-android-preview][2] 15 | 16 | ## Installation 17 | 18 | ``` 19 | npm install react-native-smart-splash-screen --save 20 | ``` 21 | 22 | ## Notice 23 | 24 | It can only be used greater-than-equal react-native 0.4.0 for ios, if you want to use the package less-than react-native 0.4.0, use `npm install react-native-smart-splash-screen@untilRN0.40 --save` 25 | 26 | ## Installation (iOS) 27 | 28 | * Drag RCTSplashScreen.xcodeproj to your project on Xcode. 29 | 30 | * Click on your main project file (the one that represents the .xcodeproj) select Build Phases and drag libRCTSplashScreen.a from the Products folder inside the RCTSplashScreen.xcodeproj. 31 | 32 | * Look for Header Search Paths and make sure it contains $(SRCROOT)/../../../react-native/React as recursive. 33 | 34 | * In your project, Look for Header Search Paths and make sure it contains $(SRCROOT)/../node_modules/react-native-smart-splash-screen/ios/RCTSplashScreen/RCTSplashScreen 35 | 36 | * delete your project's LaunchScreen.xib 37 | 38 | * Drag SplashScreenResource folder to your project *if you want change image, replace splash.png or add a image with your custom name* 39 | 40 | * In AppDelegate.m 41 | 42 | ``` 43 | 44 | ... 45 | #import "RCTSplashScreen.h" //import interface 46 | ... 47 | RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation 48 | moduleName:@"ReactNativeComponents" 49 | initialProperties:nil 50 | launchOptions:launchOptions]; 51 | 52 | //[RCTSplashScreen open:rootView]; 53 | [RCTSplashScreen open:rootView withImageNamed:@"splash"]; // activate splashscreen, imagename from LaunchScreen.xib 54 | 55 | rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; 56 | 57 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 58 | UIViewController *rootViewController = [UIViewController new]; 59 | rootViewController.view = rootView; 60 | self.window.rootViewController = rootViewController; 61 | [self.window makeKeyAndVisible]; 62 | return YES; 63 | 64 | ``` 65 | 66 | 67 | ## Installation (Android) 68 | 69 | * In `android/settings.gradle` 70 | 71 | ``` 72 | ... 73 | include ':react-native-smart-splashscreen' 74 | project(':react-native-smart-splashscreen').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-smart-splash-screen/android') 75 | ``` 76 | 77 | * In `android/app/build.gradle` 78 | 79 | ``` 80 | ... 81 | dependencies { 82 | ... 83 | // From node_modules 84 | compile project(':react-native-smart-splashscreen') 85 | } 86 | ``` 87 | 88 | * Add your own `drawable/splash.png` to `android/app/src/main/res/`, it is recommended to add `drawable-?dpi` folders that you need. 89 | 90 | * in MainApplication.java 91 | 92 | ``` 93 | ... 94 | import com.reactnativecomponent.splashscreen.RCTSplashScreenPackage; //import package 95 | ... 96 | /** 97 | * A list of packages used by the app. If the app uses additional views 98 | * or modules besides the default ones, add more packages here. 99 | */ 100 | @Override 101 | protected List getPackages() { 102 | return Arrays.asList( 103 | new MainReactPackage(), 104 | new RCTSplashScreenPackage() //register Module 105 | ); 106 | } 107 | ... 108 | 109 | ``` 110 | 111 | * in MainActivity.java 112 | ``` 113 | ... 114 | import com.reactnativecomponent.splashscreen.RCTSplashScreen; //import RCTSplashScreen 115 | ... 116 | @Override 117 | protected void onCreate(Bundle savedInstanceState) { 118 | RCTSplashScreen.openSplashScreen(this); //open splashscreen 119 | //RCTSplashScreen.openSplashScreen(this, true, ImageView.ScaleType.FIT_XY); //open splashscreen fullscreen 120 | super.onCreate(savedInstanceState); 121 | } 122 | ``` 123 | 124 | * In `android/app/**/styles.xml` 125 | 126 | ``` 127 | ... 128 | 129 | 133 | ... 134 | ``` 135 | 136 | ## Full Demo 137 | 138 | see [ReactNativeComponentDemos][0] 139 | 140 | 141 | ## Usage 142 | 143 | ```js 144 | ... 145 | import SplashScreen from 'react-native-smart-splash-screen' 146 | ... 147 | componentDidMount () { 148 | //SplashScreen.close(SplashScreen.animationType.scale, 850, 500) 149 | SplashScreen.close({ 150 | animationType: SplashScreen.animationType.scale, 151 | duration: 850, 152 | delay: 500, 153 | }) 154 | } 155 | ... 156 | 157 | ``` 158 | 159 | ## Method 160 | 161 | * close(animationType, duration, delay) 162 | close splash screen with custom animation 163 | 164 | * animationType: determine the type of animation. enum(animationType.none, animationType.fade, animationType.scale) 165 | * duration: determine the duration of animation 166 | * delay: determine the delay of animation 167 | 168 | 169 | [0]: https://github.com/cyqresig/ReactNativeComponentDemos 170 | [1]: http://cyqresig.github.io/img/react-native-smart-splash-screen-preview-ios-v2.3.0.gif 171 | [2]: http://cyqresig.github.io/img/react-native-smart-splash-screen-preview-android-v2.3.0.gif 172 | -------------------------------------------------------------------------------- /SplashScreen.js: -------------------------------------------------------------------------------- 1 | /* 2 | * A smart splash screen for react-native apps 3 | * https://github.com/react-native-component/react-native-smart-splash-screen/ 4 | * Released under the MIT license 5 | * Copyright (c) 2016 react-native-component 6 | */ 7 | 8 | import { 9 | NativeModules, 10 | } from 'react-native' 11 | 12 | export default NativeModules.SplashScreen -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.3" 6 | 7 | defaultConfig { 8 | minSdkVersion 16 9 | targetSdkVersion 23 10 | versionCode 1 11 | versionName "1.0" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | compile fileTree(include: ['*.jar'], dir: 'libs') 23 | compile 'com.android.support:appcompat-v7:23.4.0' 24 | compile 'com.facebook.react:react-native:+' 25 | } 26 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /android/src/main/java/com/reactnativecomponent/splashscreen/RCTSplashScreen.java: -------------------------------------------------------------------------------- 1 | package com.reactnativecomponent.splashscreen; 2 | 3 | import android.app.Activity; 4 | import android.app.Dialog; 5 | import android.content.Context; 6 | import android.view.View; 7 | import android.view.ViewGroup; 8 | import android.view.ViewGroup.LayoutParams; 9 | import android.view.animation.AlphaAnimation; 10 | import android.view.animation.Animation; 11 | import android.view.animation.AnimationSet; 12 | import android.view.animation.ScaleAnimation; 13 | import android.widget.ImageView; 14 | import android.widget.LinearLayout; 15 | 16 | import java.lang.ref.WeakReference; 17 | 18 | 19 | public class RCTSplashScreen { 20 | 21 | public static final int UIAnimationNone = 0; 22 | public static final int UIAnimationFade = 1; 23 | public static final int UIAnimationScale = 2; 24 | 25 | private static Dialog dialog; 26 | private static ImageView imageView; 27 | 28 | private static WeakReference wr_activity; 29 | 30 | protected static Activity getActivity() { 31 | return wr_activity.get(); 32 | } 33 | 34 | public static void openSplashScreen(Activity activity) { 35 | openSplashScreen(activity, false); 36 | } 37 | 38 | public static void openSplashScreen(Activity activity, boolean isFullScreen) { 39 | openSplashScreen(activity, isFullScreen, ImageView.ScaleType.CENTER_CROP); 40 | } 41 | 42 | public static void openSplashScreen(final Activity activity, final boolean isFullScreen, final ImageView.ScaleType scaleType) { 43 | if (activity == null) return; 44 | wr_activity = new WeakReference<>(activity); 45 | final int drawableId = getImageId(); 46 | if ((dialog != null && dialog.isShowing())||(drawableId == 0)) { 47 | return; 48 | } 49 | activity.runOnUiThread(new Runnable() { 50 | public void run() { 51 | 52 | if(!getActivity().isFinishing()) { 53 | Context context = getActivity(); 54 | imageView = new ImageView(context); 55 | 56 | imageView.setImageResource(drawableId); 57 | 58 | LayoutParams layoutParams = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 59 | imageView.setLayoutParams(layoutParams); 60 | 61 | imageView.setImageResource(drawableId); 62 | imageView.setScaleType(scaleType); 63 | 64 | dialog = new Dialog(context, isFullScreen ? android.R.style.Theme_Translucent_NoTitleBar_Fullscreen : android.R.style.Theme_Translucent_NoTitleBar); 65 | 66 | // if ((getActivity().getWindow().getAttributes().flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) 67 | // == WindowManager.LayoutParams.FLAG_FULLSCREEN) { 68 | // dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 69 | // WindowManager.LayoutParams.FLAG_FULLSCREEN); 70 | // } 71 | dialog.setContentView(imageView); 72 | dialog.setCancelable(false); 73 | dialog.show(); 74 | } 75 | 76 | } 77 | }); 78 | } 79 | 80 | public static void removeSplashScreen(Activity activity, final int animationType,final int duration) { 81 | if (activity == null) { 82 | activity = getActivity(); 83 | if(activity == null) return; 84 | } 85 | activity.runOnUiThread(new Runnable() { 86 | public void run() { 87 | if (dialog != null && dialog.isShowing()) { 88 | AnimationSet animationSet = new AnimationSet(true); 89 | 90 | if(animationType == UIAnimationScale) { 91 | AlphaAnimation fadeOut = new AlphaAnimation(1, 0); 92 | fadeOut.setDuration(duration); 93 | animationSet.addAnimation(fadeOut); 94 | 95 | ScaleAnimation scale = new ScaleAnimation(1, 1.5f, 1, 1.5f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.65f); 96 | scale.setDuration(duration); 97 | animationSet.addAnimation(scale); 98 | } 99 | else if(animationType == UIAnimationFade) { 100 | AlphaAnimation fadeOut = new AlphaAnimation(1, 0); 101 | fadeOut.setDuration(duration); 102 | animationSet.addAnimation(fadeOut); 103 | } 104 | else { 105 | AlphaAnimation fadeOut = new AlphaAnimation(1, 0); 106 | fadeOut.setDuration(0); 107 | animationSet.addAnimation(fadeOut); 108 | } 109 | 110 | final View view = ((ViewGroup)dialog.getWindow().getDecorView()).getChildAt(0); 111 | view.startAnimation(animationSet); 112 | 113 | animationSet.setAnimationListener(new Animation.AnimationListener() { 114 | @Override 115 | public void onAnimationStart(Animation animation) { 116 | } 117 | @Override 118 | public void onAnimationRepeat(Animation animation) { 119 | } 120 | @Override 121 | public void onAnimationEnd(Animation animation) { 122 | view.post(new Runnable() { 123 | @Override 124 | public void run() { 125 | dialog.dismiss(); 126 | dialog = null; 127 | imageView = null; 128 | } 129 | }); 130 | } 131 | }); 132 | } 133 | } 134 | }); 135 | } 136 | 137 | private static int getImageId() { 138 | int drawableId = getActivity().getResources().getIdentifier("splash", "drawable", getActivity().getClass().getPackage().getName()); 139 | if (drawableId == 0) { 140 | drawableId = getActivity().getResources().getIdentifier("splash", "drawable", getActivity().getPackageName()); 141 | } 142 | return drawableId; 143 | } 144 | 145 | 146 | } 147 | -------------------------------------------------------------------------------- /android/src/main/java/com/reactnativecomponent/splashscreen/RCTSplashScreenModule.java: -------------------------------------------------------------------------------- 1 | package com.reactnativecomponent.splashscreen; 2 | 3 | import android.os.Handler; 4 | import android.support.annotation.Nullable; 5 | 6 | import com.facebook.react.bridge.ReactApplicationContext; 7 | import com.facebook.react.bridge.ReactContextBaseJavaModule; 8 | import com.facebook.react.bridge.ReactMethod; 9 | import com.facebook.react.bridge.ReadableMap; 10 | 11 | import java.util.Collections; 12 | import java.util.HashMap; 13 | import java.util.Map; 14 | 15 | 16 | public class RCTSplashScreenModule extends ReactContextBaseJavaModule { 17 | 18 | public RCTSplashScreenModule(ReactApplicationContext reactContext) { 19 | super(reactContext); 20 | } 21 | 22 | @Override 23 | public String getName() { 24 | return "SplashScreen"; 25 | } 26 | 27 | @ReactMethod 28 | public void close(ReadableMap options) { 29 | 30 | int animationType = RCTSplashScreen.UIAnimationNone; 31 | int duration = 0; 32 | int delay = 0; 33 | 34 | if(options != null) { 35 | if(options.hasKey("animationType")) { 36 | animationType = options.getInt("animationType"); 37 | } 38 | if(options.hasKey("duration")) { 39 | duration = options.getInt("duration"); 40 | } 41 | if(options.hasKey("delay")) { 42 | delay = options.getInt("delay"); 43 | } 44 | } 45 | 46 | if(animationType == RCTSplashScreen.UIAnimationNone) { 47 | delay = 0; 48 | } 49 | 50 | final int final_animationType = animationType; 51 | final int final_duration = duration; 52 | 53 | final Handler handler = new Handler(); 54 | handler.postDelayed(new Runnable() { 55 | public void run() { 56 | RCTSplashScreen.removeSplashScreen(getCurrentActivity(), final_animationType, final_duration); 57 | } 58 | }, delay); 59 | } 60 | 61 | 62 | @Nullable 63 | @Override 64 | public Map getConstants() { 65 | return Collections.unmodifiableMap(new HashMap() { 66 | { 67 | put("animationType", getAnimationTypes()); 68 | } 69 | private Map getAnimationTypes() { 70 | return Collections.unmodifiableMap(new HashMap() { 71 | { 72 | put("none", RCTSplashScreen.UIAnimationNone); 73 | put("fade", RCTSplashScreen.UIAnimationFade); 74 | put("scale", RCTSplashScreen.UIAnimationScale); 75 | } 76 | }); 77 | } 78 | }); 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /android/src/main/java/com/reactnativecomponent/splashscreen/RCTSplashScreenPackage.java: -------------------------------------------------------------------------------- 1 | package com.reactnativecomponent.splashscreen; 2 | 3 | import com.facebook.react.ReactPackage; 4 | import com.facebook.react.bridge.JavaScriptModule; 5 | import com.facebook.react.bridge.NativeModule; 6 | import com.facebook.react.bridge.ReactApplicationContext; 7 | import com.facebook.react.uimanager.ViewManager; 8 | 9 | import java.util.Arrays; 10 | import java.util.Collections; 11 | import java.util.List; 12 | 13 | 14 | public class RCTSplashScreenPackage implements ReactPackage { 15 | 16 | @Override 17 | public List createNativeModules(ReactApplicationContext reactContext) { 18 | return Arrays.asList( 19 | new RCTSplashScreenModule(reactContext) 20 | ); 21 | } 22 | 23 | public List> createJSModules() { 24 | return Collections.emptyList(); 25 | } 26 | 27 | @Override 28 | public List createViewManagers(ReactApplicationContext reactContext) { 29 | return Arrays.asList(); 30 | } 31 | } -------------------------------------------------------------------------------- /ios/RCTSplashScreen/RCTSplashScreen.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 9F90C2281D619E9400F3E238 /* RCTSplashScreen.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 9F90C2271D619E9400F3E238 /* RCTSplashScreen.h */; }; 11 | 9F90C22A1D619E9400F3E238 /* RCTSplashScreen.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F90C2291D619E9400F3E238 /* RCTSplashScreen.m */; }; 12 | /* End PBXBuildFile section */ 13 | 14 | /* Begin PBXCopyFilesBuildPhase section */ 15 | 9F90C2221D619E9400F3E238 /* CopyFiles */ = { 16 | isa = PBXCopyFilesBuildPhase; 17 | buildActionMask = 2147483647; 18 | dstPath = "include/$(PRODUCT_NAME)"; 19 | dstSubfolderSpec = 16; 20 | files = ( 21 | 9F90C2281D619E9400F3E238 /* RCTSplashScreen.h in CopyFiles */, 22 | ); 23 | runOnlyForDeploymentPostprocessing = 0; 24 | }; 25 | /* End PBXCopyFilesBuildPhase section */ 26 | 27 | /* Begin PBXFileReference section */ 28 | 9F90C2241D619E9400F3E238 /* libRCTSplashScreen.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTSplashScreen.a; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | 9F90C2271D619E9400F3E238 /* RCTSplashScreen.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTSplashScreen.h; sourceTree = ""; }; 30 | 9F90C2291D619E9400F3E238 /* RCTSplashScreen.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCTSplashScreen.m; sourceTree = ""; }; 31 | /* End PBXFileReference section */ 32 | 33 | /* Begin PBXFrameworksBuildPhase section */ 34 | 9F90C2211D619E9400F3E238 /* Frameworks */ = { 35 | isa = PBXFrameworksBuildPhase; 36 | buildActionMask = 2147483647; 37 | files = ( 38 | ); 39 | runOnlyForDeploymentPostprocessing = 0; 40 | }; 41 | /* End PBXFrameworksBuildPhase section */ 42 | 43 | /* Begin PBXGroup section */ 44 | 9F90C21B1D619E9400F3E238 = { 45 | isa = PBXGroup; 46 | children = ( 47 | 9F90C2261D619E9400F3E238 /* RCTSplashScreen */, 48 | 9F90C2251D619E9400F3E238 /* Products */, 49 | ); 50 | sourceTree = ""; 51 | }; 52 | 9F90C2251D619E9400F3E238 /* Products */ = { 53 | isa = PBXGroup; 54 | children = ( 55 | 9F90C2241D619E9400F3E238 /* libRCTSplashScreen.a */, 56 | ); 57 | name = Products; 58 | sourceTree = ""; 59 | }; 60 | 9F90C2261D619E9400F3E238 /* RCTSplashScreen */ = { 61 | isa = PBXGroup; 62 | children = ( 63 | 9F90C2271D619E9400F3E238 /* RCTSplashScreen.h */, 64 | 9F90C2291D619E9400F3E238 /* RCTSplashScreen.m */, 65 | ); 66 | path = RCTSplashScreen; 67 | sourceTree = ""; 68 | }; 69 | /* End PBXGroup section */ 70 | 71 | /* Begin PBXNativeTarget section */ 72 | 9F90C2231D619E9400F3E238 /* RCTSplashScreen */ = { 73 | isa = PBXNativeTarget; 74 | buildConfigurationList = 9F90C22D1D619E9400F3E238 /* Build configuration list for PBXNativeTarget "RCTSplashScreen" */; 75 | buildPhases = ( 76 | 9F90C2201D619E9400F3E238 /* Sources */, 77 | 9F90C2211D619E9400F3E238 /* Frameworks */, 78 | 9F90C2221D619E9400F3E238 /* CopyFiles */, 79 | ); 80 | buildRules = ( 81 | ); 82 | dependencies = ( 83 | ); 84 | name = RCTSplashScreen; 85 | productName = RCTSplashScreen; 86 | productReference = 9F90C2241D619E9400F3E238 /* libRCTSplashScreen.a */; 87 | productType = "com.apple.product-type.library.static"; 88 | }; 89 | /* End PBXNativeTarget section */ 90 | 91 | /* Begin PBXProject section */ 92 | 9F90C21C1D619E9400F3E238 /* Project object */ = { 93 | isa = PBXProject; 94 | attributes = { 95 | LastUpgradeCheck = 0730; 96 | ORGANIZATIONNAME = "react-native-component"; 97 | TargetAttributes = { 98 | 9F90C2231D619E9400F3E238 = { 99 | CreatedOnToolsVersion = 7.3.1; 100 | }; 101 | }; 102 | }; 103 | buildConfigurationList = 9F90C21F1D619E9400F3E238 /* Build configuration list for PBXProject "RCTSplashScreen" */; 104 | compatibilityVersion = "Xcode 3.2"; 105 | developmentRegion = English; 106 | hasScannedForEncodings = 0; 107 | knownRegions = ( 108 | en, 109 | ); 110 | mainGroup = 9F90C21B1D619E9400F3E238; 111 | productRefGroup = 9F90C2251D619E9400F3E238 /* Products */; 112 | projectDirPath = ""; 113 | projectRoot = ""; 114 | targets = ( 115 | 9F90C2231D619E9400F3E238 /* RCTSplashScreen */, 116 | ); 117 | }; 118 | /* End PBXProject section */ 119 | 120 | /* Begin PBXSourcesBuildPhase section */ 121 | 9F90C2201D619E9400F3E238 /* Sources */ = { 122 | isa = PBXSourcesBuildPhase; 123 | buildActionMask = 2147483647; 124 | files = ( 125 | 9F90C22A1D619E9400F3E238 /* RCTSplashScreen.m in Sources */, 126 | ); 127 | runOnlyForDeploymentPostprocessing = 0; 128 | }; 129 | /* End PBXSourcesBuildPhase section */ 130 | 131 | /* Begin XCBuildConfiguration section */ 132 | 9F90C22B1D619E9400F3E238 /* Debug */ = { 133 | isa = XCBuildConfiguration; 134 | buildSettings = { 135 | ALWAYS_SEARCH_USER_PATHS = NO; 136 | CLANG_ANALYZER_NONNULL = YES; 137 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 138 | CLANG_CXX_LIBRARY = "libc++"; 139 | CLANG_ENABLE_MODULES = YES; 140 | CLANG_ENABLE_OBJC_ARC = YES; 141 | CLANG_WARN_BOOL_CONVERSION = YES; 142 | CLANG_WARN_CONSTANT_CONVERSION = YES; 143 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 144 | CLANG_WARN_EMPTY_BODY = YES; 145 | CLANG_WARN_ENUM_CONVERSION = YES; 146 | CLANG_WARN_INT_CONVERSION = YES; 147 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 148 | CLANG_WARN_UNREACHABLE_CODE = YES; 149 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 150 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 151 | COPY_PHASE_STRIP = NO; 152 | DEBUG_INFORMATION_FORMAT = dwarf; 153 | ENABLE_STRICT_OBJC_MSGSEND = YES; 154 | ENABLE_TESTABILITY = YES; 155 | GCC_C_LANGUAGE_STANDARD = gnu99; 156 | GCC_DYNAMIC_NO_PIC = NO; 157 | GCC_NO_COMMON_BLOCKS = YES; 158 | GCC_OPTIMIZATION_LEVEL = 0; 159 | GCC_PREPROCESSOR_DEFINITIONS = ( 160 | "DEBUG=1", 161 | "$(inherited)", 162 | ); 163 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 164 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 165 | GCC_WARN_UNDECLARED_SELECTOR = YES; 166 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 167 | GCC_WARN_UNUSED_FUNCTION = YES; 168 | GCC_WARN_UNUSED_VARIABLE = YES; 169 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 170 | MTL_ENABLE_DEBUG_INFO = YES; 171 | ONLY_ACTIVE_ARCH = YES; 172 | SDKROOT = iphoneos; 173 | }; 174 | name = Debug; 175 | }; 176 | 9F90C22C1D619E9400F3E238 /* Release */ = { 177 | isa = XCBuildConfiguration; 178 | buildSettings = { 179 | ALWAYS_SEARCH_USER_PATHS = NO; 180 | CLANG_ANALYZER_NONNULL = YES; 181 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 182 | CLANG_CXX_LIBRARY = "libc++"; 183 | CLANG_ENABLE_MODULES = YES; 184 | CLANG_ENABLE_OBJC_ARC = YES; 185 | CLANG_WARN_BOOL_CONVERSION = YES; 186 | CLANG_WARN_CONSTANT_CONVERSION = YES; 187 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 188 | CLANG_WARN_EMPTY_BODY = YES; 189 | CLANG_WARN_ENUM_CONVERSION = YES; 190 | CLANG_WARN_INT_CONVERSION = YES; 191 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 192 | CLANG_WARN_UNREACHABLE_CODE = YES; 193 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 194 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 195 | COPY_PHASE_STRIP = NO; 196 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 197 | ENABLE_NS_ASSERTIONS = NO; 198 | ENABLE_STRICT_OBJC_MSGSEND = YES; 199 | GCC_C_LANGUAGE_STANDARD = gnu99; 200 | GCC_NO_COMMON_BLOCKS = YES; 201 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 202 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 203 | GCC_WARN_UNDECLARED_SELECTOR = YES; 204 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 205 | GCC_WARN_UNUSED_FUNCTION = YES; 206 | GCC_WARN_UNUSED_VARIABLE = YES; 207 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 208 | MTL_ENABLE_DEBUG_INFO = NO; 209 | SDKROOT = iphoneos; 210 | VALIDATE_PRODUCT = YES; 211 | }; 212 | name = Release; 213 | }; 214 | 9F90C22E1D619E9400F3E238 /* Debug */ = { 215 | isa = XCBuildConfiguration; 216 | buildSettings = { 217 | HEADER_SEARCH_PATHS = ( 218 | "$(inherited)", 219 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 220 | "$(SRCROOT)/../../../react-native/React/**", 221 | ); 222 | OTHER_LDFLAGS = "-ObjC"; 223 | PRODUCT_NAME = "$(TARGET_NAME)"; 224 | SKIP_INSTALL = YES; 225 | }; 226 | name = Debug; 227 | }; 228 | 9F90C22F1D619E9400F3E238 /* Release */ = { 229 | isa = XCBuildConfiguration; 230 | buildSettings = { 231 | HEADER_SEARCH_PATHS = ( 232 | "$(inherited)", 233 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 234 | "$(SRCROOT)/../../../react-native/React/**", 235 | ); 236 | OTHER_LDFLAGS = "-ObjC"; 237 | PRODUCT_NAME = "$(TARGET_NAME)"; 238 | SKIP_INSTALL = YES; 239 | }; 240 | name = Release; 241 | }; 242 | /* End XCBuildConfiguration section */ 243 | 244 | /* Begin XCConfigurationList section */ 245 | 9F90C21F1D619E9400F3E238 /* Build configuration list for PBXProject "RCTSplashScreen" */ = { 246 | isa = XCConfigurationList; 247 | buildConfigurations = ( 248 | 9F90C22B1D619E9400F3E238 /* Debug */, 249 | 9F90C22C1D619E9400F3E238 /* Release */, 250 | ); 251 | defaultConfigurationIsVisible = 0; 252 | defaultConfigurationName = Release; 253 | }; 254 | 9F90C22D1D619E9400F3E238 /* Build configuration list for PBXNativeTarget "RCTSplashScreen" */ = { 255 | isa = XCConfigurationList; 256 | buildConfigurations = ( 257 | 9F90C22E1D619E9400F3E238 /* Debug */, 258 | 9F90C22F1D619E9400F3E238 /* Release */, 259 | ); 260 | defaultConfigurationIsVisible = 0; 261 | defaultConfigurationName = Release; 262 | }; 263 | /* End XCConfigurationList section */ 264 | }; 265 | rootObject = 9F90C21C1D619E9400F3E238 /* Project object */; 266 | } 267 | -------------------------------------------------------------------------------- /ios/RCTSplashScreen/RCTSplashScreen.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/RCTSplashScreen/RCTSplashScreen/RCTSplashScreen.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface RCTSplashScreen : NSObject 5 | 6 | typedef NS_ENUM(NSInteger, RCTCameraAspect) { 7 | UIAnimationNone = 0, 8 | UIAnimationFade = 1, 9 | UIAnimationScale = 2 10 | }; 11 | 12 | + (void)open:(RCTRootView *)v; 13 | + (void)open:(RCTRootView *)v withImageNamed:(NSString *)imgName; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /ios/RCTSplashScreen/RCTSplashScreen/RCTSplashScreen.m: -------------------------------------------------------------------------------- 1 | 2 | #import "RCTSplashScreen.h" 3 | 4 | static RCTRootView *rootView = nil; 5 | 6 | @interface RCTSplashScreen() 7 | 8 | @end 9 | 10 | @implementation RCTSplashScreen 11 | 12 | RCT_EXPORT_MODULE(SplashScreen) 13 | 14 | 15 | + (void)open:(RCTRootView *)v { 16 | [RCTSplashScreen open:v withImageNamed:@"splash"]; 17 | } 18 | 19 | 20 | + (void)open:(RCTRootView *)v withImageNamed:(NSString *)imageName { 21 | rootView = v; 22 | 23 | UIImageView *view = [[UIImageView alloc]initWithFrame:[UIScreen mainScreen].bounds]; 24 | 25 | view.image = [UIImage imageNamed:imageName]; 26 | view.contentMode = UIViewContentModeScaleAspectFill; 27 | 28 | [[NSNotificationCenter defaultCenter] removeObserver:rootView name:RCTContentDidAppearNotification object:rootView]; 29 | 30 | [rootView setLoadingView:view]; 31 | } 32 | 33 | RCT_EXPORT_METHOD(close:(NSDictionary *)options) { 34 | if (!rootView) { 35 | return; 36 | } 37 | 38 | int animationType = UIAnimationNone; 39 | int duration = 0; 40 | int delay = 0; 41 | 42 | if(options != nil) { 43 | 44 | NSArray *keys = [options allKeys]; 45 | 46 | if([keys containsObject:@"animationType"]) { 47 | animationType = [[options objectForKey:@"animationType"] intValue]; 48 | } 49 | if([keys containsObject:@"duration"]) { 50 | duration = [[options objectForKey:@"duration"] intValue]; 51 | } 52 | if([keys containsObject:@"delay"]) { 53 | delay = [[options objectForKey:@"delay"] intValue]; 54 | } 55 | } 56 | 57 | if(animationType == UIAnimationNone) { 58 | rootView.loadingViewFadeDelay = 0; 59 | rootView.loadingViewFadeDuration = 0; 60 | } 61 | else { 62 | rootView.loadingViewFadeDelay = delay / 1000.0; 63 | rootView.loadingViewFadeDuration = duration / 1000.0; 64 | } 65 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(rootView.loadingViewFadeDelay * NSEC_PER_SEC)), 66 | dispatch_get_main_queue(), 67 | ^{ 68 | [UIView animateWithDuration:rootView.loadingViewFadeDuration 69 | animations:^{ 70 | if(animationType == UIAnimationScale) { 71 | rootView.loadingView.transform = CGAffineTransformMakeScale(1.5, 1.5); 72 | rootView.loadingView.alpha = 0; 73 | } 74 | else { 75 | rootView.loadingView.alpha = 0; 76 | } 77 | } completion:^(__unused BOOL finished) { 78 | [rootView.loadingView removeFromSuperview]; 79 | }]; 80 | }); 81 | 82 | } 83 | 84 | - (NSDictionary *)constantsToExport 85 | { 86 | return @{ 87 | @"animationType": @{ 88 | @"none": @(UIAnimationNone), 89 | @"fade": @(UIAnimationFade), 90 | @"scale": @(UIAnimationScale), 91 | } 92 | }; 93 | } 94 | 95 | @end 96 | -------------------------------------------------------------------------------- /ios/SplashScreenResource/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /ios/SplashScreenResource/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/react-native-component/react-native-smart-splash-screen/08293d1ec269af912db1410daa2cec697ab49ee7/ios/SplashScreenResource/splash.png -------------------------------------------------------------------------------- /note.md: -------------------------------------------------------------------------------- 1 | 2 | * 要注意 ios 使用默认实现的addLoadingView的方法, 在主View之前增加一个view来实现splashscreen 3 | 要注意 android 使用新增一个Dialog的方式来实现splashscreen 4 | 5 | * 要注意 android 代码获取图片资源时(无文件后缀名), png与jpg都可以获取到 6 | 但是在 ios 代码获取图片资源时(无文件后缀名), 只能获取到png 7 | 8 | * (废弃, bitmap消耗过大)要注意 android 使用了bitmap操作图片进行了裁剪, 9 | 为使launchScreen时设置的背景图与splashScreen的图片展现一致(android的顶部的statusBar与底部的navigationBar的高度会影响Dialog) 10 | 11 | * 要注意 android 给windowbackground设置背景图也会加大每帧渲染的消耗, 并且会有可能导致奇怪的闪屏bug, 故也废弃 12 | * 要注意 android 采用起始application设置window透明色的方式 13 | * 要注意 android 从0.3x版本开始, 组件package的加载放至application中, 故将package加载和splashscreen显示二个动作分开, 14 | 否则无法保证splashscreen显示的动作正好在onCreate操作之前 -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-smart-splash-screen", 3 | "version": "2.3.5", 4 | "description": "A smart splash screen for React Native apps", 5 | "main": "SplashScreen.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/react-native-component/react-native-smart-splash-screen.git" 12 | }, 13 | "keywords": [ 14 | "react-native", 15 | "smart", 16 | "splash", 17 | "screen", 18 | "splashscreen", 19 | "component" 20 | ], 21 | "author": "HISAME SHIZUMARU", 22 | "license": "MIT", 23 | "bugs": { 24 | "url": "https://github.com/react-native-component/react-native-smart-splash-screen/issues" 25 | }, 26 | "homepage": "https://github.com/react-native-component/react-native-smart-splash-screen#readme", 27 | "peerDependencies": { 28 | "react-native": ">=0.40.0" 29 | } 30 | } 31 | --------------------------------------------------------------------------------