react-native-custom-splash 2.2.0 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-custom-splash",
3
- "version": "2.2.0",
3
+ "version": "3.0.1",
4
4
  "description": "A custom splash screen module for React Native with native iOS and Android support, fully compatible with Expo",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
@@ -17,7 +17,7 @@
17
17
  "android",
18
18
  "native-module"
19
19
  ],
20
- "author": "Your Name",
20
+ "author": "Vijay Kishan",
21
21
  "license": "MIT",
22
22
  "repository": {
23
23
  "type": "git",
@@ -8,7 +8,7 @@ const {
8
8
  } = require('@expo/config-plugins');
9
9
  const path = require('path');
10
10
  const fs = require('fs');
11
- const withCustomiOSSplash = require('./withCustomSplash');
11
+ const withForcediOSSplash = require('./withCustomSplash');
12
12
 
13
13
  /**
14
14
  * Validate and normalize plugin configuration
@@ -531,6 +531,6 @@ module.exports = (config, props = {}) => {
531
531
 
532
532
  return withPlugins(config, [
533
533
  [withSplashScreenAndroid, pluginConfig],
534
- [withCustomiOSSplash, pluginConfig],
534
+ [withForcediOSSplash, pluginConfig],
535
535
  ]);
536
536
  };
@@ -3,10 +3,19 @@ const path = require('path');
3
3
  const fs = require('fs');
4
4
 
5
5
  /**
6
- * COMPLETE iOS Splash Screen Setup
7
- * This runs AFTER Expo's default splash and overwrites everything
6
+ * FINAL WORKING iOS Splash - Xcode Compatible
8
7
  */
9
- function withCustomiOSSplash(config, pluginConfig) {
8
+ function withForcediOSSplash(config, pluginConfig) {
9
+ // Disable Expo's splash
10
+ config = {
11
+ ...config,
12
+ splash: undefined,
13
+ ios: {
14
+ ...config.ios,
15
+ splash: undefined
16
+ }
17
+ };
18
+
10
19
  return withDangerousMod(config, [
11
20
  'ios',
12
21
  async (config) => {
@@ -14,129 +23,164 @@ function withCustomiOSSplash(config, pluginConfig) {
14
23
  const iosPath = config.modRequest.platformProjectRoot;
15
24
  const projectName = config.modRequest.projectName;
16
25
 
17
- console.log('\n🚀 Setting up custom iOS splash screen...\n');
26
+ console.log('\n🔥 SETTING UP CUSTOM SPLASH...\n');
27
+
28
+ // Delete ALL old splash files
29
+ const filesToDelete = [
30
+ path.join(iosPath, projectName, 'SplashScreen.storyboard'),
31
+ path.join(iosPath, projectName, 'LaunchScreen.storyboard'),
32
+ path.join(iosPath, projectName, 'Images.xcassets', 'SplashScreenLegacy.imageset'),
33
+ path.join(iosPath, projectName, 'Images.xcassets', 'SplashScreen.imageset'),
34
+ path.join(iosPath, projectName, 'Images.xcassets', 'SplashScreenBackground.imageset'),
35
+ ];
36
+
37
+ filesToDelete.forEach(filePath => {
38
+ try {
39
+ if (fs.existsSync(filePath)) {
40
+ if (fs.lstatSync(filePath).isDirectory()) {
41
+ fs.rmSync(filePath, { recursive: true, force: true });
42
+ } else {
43
+ fs.unlinkSync(filePath);
44
+ }
45
+ }
46
+ } catch (e) {
47
+ // Ignore
48
+ }
49
+ });
18
50
 
19
- // 1. Update Info.plist
51
+ // Update Info.plist
20
52
  const plistPath = path.join(iosPath, projectName, 'Info.plist');
21
53
  if (fs.existsSync(plistPath)) {
22
54
  let plist = fs.readFileSync(plistPath, 'utf8');
55
+ plist = plist.replace(/<key>UILaunchStoryboardName<\/key>\s*<string>.*?<\/string>/g, '');
56
+ plist = plist.replace(/<key>UILaunchScreen<\/key>[\s\S]*?<\/dict>/g, '');
23
57
 
24
- // Force LaunchScreen
25
- if (!plist.includes('<key>UILaunchStoryboardName</key>')) {
58
+ if (!plist.includes('UILaunchStoryboardName')) {
26
59
  plist = plist.replace(
27
60
  '</dict>\n</plist>',
28
61
  '\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n</dict>\n</plist>'
29
62
  );
30
- } else {
31
- plist = plist.replace(
32
- /<key>UILaunchStoryboardName<\/key>\s*<string>.*?<\/string>/,
33
- '<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>'
34
- );
35
63
  }
36
64
 
37
- // Remove UILaunchScreen dictionary
38
- plist = plist.replace(/<key>UILaunchScreen<\/key>[\s\S]*?<\/dict>/g, '');
39
-
40
65
  fs.writeFileSync(plistPath, plist);
41
66
  console.log('✅ Info.plist updated');
42
67
  }
43
68
 
44
- // 2. Delete ALL old storyboards
45
- const storyboards = [
46
- path.join(iosPath, projectName, 'SplashScreen.storyboard'),
47
- path.join(iosPath, projectName, 'LaunchScreen.storyboard'),
48
- ];
49
-
50
- storyboards.forEach(sb => {
51
- if (fs.existsSync(sb)) {
52
- fs.unlinkSync(sb);
53
- console.log(`🗑️ Deleted: ${path.basename(sb)}`);
54
- }
55
- });
56
-
57
- // 3. Delete SplashScreenLegacy
58
- const legacyPath = path.join(iosPath, projectName, 'Images.xcassets', 'SplashScreenLegacy.imageset');
59
- if (fs.existsSync(legacyPath)) {
60
- fs.rmSync(legacyPath, { recursive: true });
61
- console.log('🗑️ Deleted: SplashScreenLegacy');
62
- }
63
-
64
- // 4. Delete SplashScreen imageset (from Expo)
65
- const splashImagePath = path.join(iosPath, projectName, 'Images.xcassets', 'SplashScreen.imageset');
66
- if (fs.existsSync(splashImagePath)) {
67
- fs.rmSync(splashImagePath, { recursive: true });
68
- console.log('🗑️ Deleted: SplashScreen');
69
- }
70
-
71
- // 5. Copy user images
72
69
  const assetsPath = path.join(iosPath, projectName, 'Images.xcassets');
73
70
  let hasImage = false;
74
71
  let hasLogo = false;
75
72
 
73
+ // Copy splash_image
76
74
  if (pluginConfig.image) {
77
75
  const srcImage = path.join(projectRoot, pluginConfig.image);
78
76
  if (fs.existsSync(srcImage)) {
79
- const destDir = path.join(assetsPath, 'splash_image.imageset');
77
+ const destDir = path.join(assetsPath, 'SplashImage.imageset');
78
+
79
+ if (fs.existsSync(destDir)) {
80
+ fs.rmSync(destDir, { recursive: true, force: true });
81
+ }
80
82
  fs.mkdirSync(destDir, { recursive: true });
81
83
 
82
- // Copy for all scales
83
- ['', '@2x', '@3x'].forEach(scale => {
84
- const destFile = path.join(destDir, `splash_image${scale}.png`);
85
- fs.copyFileSync(srcImage, destFile);
86
- });
84
+ // Copy image
85
+ fs.copyFileSync(srcImage, path.join(destDir, 'splash.png'));
87
86
 
88
87
  // Create Contents.json
89
88
  const contents = {
90
89
  images: [
91
- { idiom: 'universal', filename: 'splash_image.png', scale: '1x' },
92
- { idiom: 'universal', filename: 'splash_image@2x.png', scale: '2x' },
93
- { idiom: 'universal', filename: 'splash_image@3x.png', scale: '3x' }
90
+ {
91
+ filename: 'splash.png',
92
+ idiom: 'universal',
93
+ scale: '1x'
94
+ },
95
+ {
96
+ filename: 'splash.png',
97
+ idiom: 'universal',
98
+ scale: '2x'
99
+ },
100
+ {
101
+ filename: 'splash.png',
102
+ idiom: 'universal',
103
+ scale: '3x'
104
+ }
94
105
  ],
95
- info: { author: 'xcode', version: 1 }
106
+ info: {
107
+ author: 'xcode',
108
+ version: 1
109
+ }
96
110
  };
97
- fs.writeFileSync(path.join(destDir, 'Contents.json'), JSON.stringify(contents, null, 2));
111
+
112
+ fs.writeFileSync(
113
+ path.join(destDir, 'Contents.json'),
114
+ JSON.stringify(contents, null, 2)
115
+ );
98
116
 
99
117
  hasImage = true;
100
- console.log('✅ Copied: splash_image');
118
+ console.log('✅ Background image copied: SplashImage');
101
119
  }
102
120
  }
103
121
 
122
+ // Copy splash_logo
104
123
  if (pluginConfig.logo) {
105
124
  const srcLogo = path.join(projectRoot, pluginConfig.logo);
106
125
  if (fs.existsSync(srcLogo)) {
107
- const destDir = path.join(assetsPath, 'splash_logo.imageset');
126
+ const destDir = path.join(assetsPath, 'SplashLogo.imageset');
127
+
128
+ if (fs.existsSync(destDir)) {
129
+ fs.rmSync(destDir, { recursive: true, force: true });
130
+ }
108
131
  fs.mkdirSync(destDir, { recursive: true });
109
132
 
110
- // Copy for all scales
111
- ['', '@2x', '@3x'].forEach(scale => {
112
- const destFile = path.join(destDir, `splash_logo${scale}.png`);
113
- fs.copyFileSync(srcLogo, destFile);
114
- });
133
+ // Copy logo
134
+ fs.copyFileSync(srcLogo, path.join(destDir, 'logo.png'));
115
135
 
116
136
  // Create Contents.json
117
137
  const contents = {
118
138
  images: [
119
- { idiom: 'universal', filename: 'splash_logo.png', scale: '1x' },
120
- { idiom: 'universal', filename: 'splash_logo@2x.png', scale: '2x' },
121
- { idiom: 'universal', filename: 'splash_logo@3x.png', scale: '3x' }
139
+ {
140
+ filename: 'logo.png',
141
+ idiom: 'universal',
142
+ scale: '1x'
143
+ },
144
+ {
145
+ filename: 'logo.png',
146
+ idiom: 'universal',
147
+ scale: '2x'
148
+ },
149
+ {
150
+ filename: 'logo.png',
151
+ idiom: 'universal',
152
+ scale: '3x'
153
+ }
122
154
  ],
123
- info: { author: 'xcode', version: 1 }
155
+ info: {
156
+ author: 'xcode',
157
+ version: 1
158
+ }
124
159
  };
125
- fs.writeFileSync(path.join(destDir, 'Contents.json'), JSON.stringify(contents, null, 2));
160
+
161
+ fs.writeFileSync(
162
+ path.join(destDir, 'Contents.json'),
163
+ JSON.stringify(contents, null, 2)
164
+ );
126
165
 
127
166
  hasLogo = true;
128
- console.log('✅ Copied: splash_logo');
167
+ console.log('✅ Logo image copied: SplashLogo');
129
168
  }
130
169
  }
131
170
 
132
- // 6. Create NEW LaunchScreen.storyboard
133
- const storyboard = createStoryboard(hasImage, hasLogo, pluginConfig.backgroundColor);
171
+ // Create LaunchScreen.storyboard
172
+ const storyboard = createXcodeStoryboard(hasImage, hasLogo, pluginConfig.backgroundColor);
134
173
  const storyboardPath = path.join(iosPath, projectName, 'LaunchScreen.storyboard');
174
+
175
+ if (fs.existsSync(storyboardPath)) {
176
+ fs.unlinkSync(storyboardPath);
177
+ }
178
+
135
179
  fs.writeFileSync(storyboardPath, storyboard);
136
180
 
137
- console.log('✅ Created: LaunchScreen.storyboard');
138
- console.log(` Background: ${hasImage ? 'splash_image ✓' : 'color only'}`);
139
- console.log(` Logo: ${hasLogo ? 'splash_logo ✓' : 'none'}`);
181
+ console.log('✅ LaunchScreen.storyboard created!');
182
+ console.log(` Background: ${hasImage ? 'SplashImage ✓' : 'Color only'}`);
183
+ console.log(` Logo: ${hasLogo ? 'SplashLogo ✓' : 'None'}`);
140
184
  console.log(` Color: ${pluginConfig.backgroundColor}\n`);
141
185
 
142
186
  return config;
@@ -144,61 +188,73 @@ function withCustomiOSSplash(config, pluginConfig) {
144
188
  ]);
145
189
  }
146
190
 
147
- function createStoryboard(hasImage, hasLogo, bgColor) {
191
+ function createXcodeStoryboard(hasImage, hasLogo, bgColor) {
148
192
  const color = bgColor.replace('#', '');
149
193
  const r = parseInt(color.substr(0, 2), 16) / 255;
150
194
  const g = parseInt(color.substr(2, 2), 16) / 255;
151
195
  const b = parseInt(color.substr(4, 2), 16) / 255;
152
196
 
153
- const bgImageView = hasImage ? `
154
- <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="splash_image" translatesAutoresizingMaskIntoConstraints="NO" id="bgImg">
155
- <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
156
- </imageView>` : '';
157
-
158
- const logoImageView = hasLogo ? `
159
- <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="splash_logo" translatesAutoresizingMaskIntoConstraints="NO" id="logoImg">
160
- <rect key="frame" x="132" y="348" width="150" height="150"/>
161
- <constraints>
162
- <constraint firstAttribute="width" constant="150" id="logoW"/>
163
- <constraint firstAttribute="height" constant="150" id="logoH"/>
164
- </constraints>
165
- </imageView>` : '';
166
-
167
- const bgConstraints = hasImage ? `
168
- <constraint firstItem="bgImg" firstAttribute="top" secondItem="view" secondAttribute="top"/>
169
- <constraint firstItem="bgImg" firstAttribute="leading" secondItem="view" secondAttribute="leading"/>
170
- <constraint firstItem="bgImg" firstAttribute="trailing" secondItem="view" secondAttribute="trailing"/>
171
- <constraint firstItem="bgImg" firstAttribute="bottom" secondItem="view" secondAttribute="bottom"/>` : '';
172
-
173
- const logoConstraints = hasLogo ? `
174
- <constraint firstItem="logoImg" firstAttribute="centerX" secondItem="view" secondAttribute="centerX"/>
175
- <constraint firstItem="logoImg" firstAttribute="centerY" secondItem="view" secondAttribute="centerY"/>` : '';
176
-
177
- const resources = [];
178
- if (hasImage) resources.push(' <image name="splash_image" width="1242" height="2688"/>');
179
- if (hasLogo) resources.push(' <image name="splash_logo" width="512" height="512"/>');
197
+ // Build subviews
198
+ let subviews = '';
199
+ let constraints = '';
200
+ let resources = '';
201
+
202
+ if (hasImage) {
203
+ subviews += `
204
+ <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="SplashImage" translatesAutoresizingMaskIntoConstraints="NO" id="splash-bg">
205
+ <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
206
+ </imageView>`;
207
+
208
+ constraints += `
209
+ <constraint firstItem="splash-bg" firstAttribute="top" secondItem="Ze5-6b-2t3" secondAttribute="top" id="bg-top"/>
210
+ <constraint firstItem="splash-bg" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leading" id="bg-leading"/>
211
+ <constraint firstItem="splash-bg" firstAttribute="trailing" secondItem="Ze5-6b-2t3" secondAttribute="trailing" id="bg-trailing"/>
212
+ <constraint firstItem="splash-bg" firstAttribute="bottom" secondItem="Ze5-6b-2t3" secondAttribute="bottom" id="bg-bottom"/>`;
213
+
214
+ resources += `
215
+ <image name="SplashImage" width="1242" height="2688"/>`;
216
+ }
217
+
218
+ if (hasLogo) {
219
+ subviews += `
220
+ <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="SplashLogo" translatesAutoresizingMaskIntoConstraints="NO" id="splash-logo">
221
+ <rect key="frame" x="132" y="373" width="150" height="150"/>
222
+ <constraints>
223
+ <constraint firstAttribute="width" constant="150" id="logo-width"/>
224
+ <constraint firstAttribute="height" constant="150" id="logo-height"/>
225
+ </constraints>
226
+ </imageView>`;
227
+
228
+ constraints += `
229
+ <constraint firstItem="splash-logo" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="logo-centerx"/>
230
+ <constraint firstItem="splash-logo" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="logo-centery"/>`;
231
+
232
+ resources += `
233
+ <image name="SplashLogo" width="512" height="512"/>`;
234
+ }
180
235
 
181
236
  return `<?xml version="1.0" encoding="UTF-8"?>
182
- <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="21507" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
237
+ <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="21701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
183
238
  <device id="retina6_1" orientation="portrait" appearance="light"/>
184
239
  <dependencies>
185
240
  <deployment identifier="iOS"/>
186
- <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21505"/>
241
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21679"/>
187
242
  <capability name="Safe area layout guides" minToolsVersion="9.0"/>
188
243
  <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
189
244
  </dependencies>
190
245
  <scenes>
246
+ <!--View Controller-->
191
247
  <scene sceneID="EHf-IW-A2E">
192
248
  <objects>
193
249
  <viewController id="01J-lp-oVM" sceneMemberID="viewController">
194
- <view key="view" contentMode="scaleToFill" id="view">
250
+ <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
195
251
  <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
196
252
  <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
197
- <subviews>${bgImageView}${logoImageView}
253
+ <subviews>${subviews}
198
254
  </subviews>
199
- <viewLayoutGuide key="safeArea" id="safeArea"/>
255
+ <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
200
256
  <color key="backgroundColor" red="${r}" green="${g}" blue="${b}" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
201
- <constraints>${bgConstraints}${logoConstraints}
257
+ <constraints>${constraints}
202
258
  </constraints>
203
259
  </view>
204
260
  </viewController>
@@ -207,10 +263,9 @@ function createStoryboard(hasImage, hasLogo, bgColor) {
207
263
  <point key="canvasLocation" x="53" y="375"/>
208
264
  </scene>
209
265
  </scenes>
210
- <resources>
211
- ${resources.join('\n')}
266
+ <resources>${resources}
212
267
  </resources>
213
268
  </document>`;
214
269
  }
215
270
 
216
- module.exports = withCustomiOSSplash;
271
+ module.exports = withForcediOSSplash;