react-native-universal-keyboard-aware-scrollview 1.0.0

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.
Files changed (84) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +387 -0
  3. package/android/app/build.gradle +182 -0
  4. package/android/app/debug.keystore +0 -0
  5. package/android/app/proguard-rules.pro +14 -0
  6. package/android/app/src/debug/AndroidManifest.xml +7 -0
  7. package/android/app/src/debugOptimized/AndroidManifest.xml +7 -0
  8. package/android/app/src/main/AndroidManifest.xml +25 -0
  9. package/android/app/src/main/java/com/anonymous/reactnativeuniversalkeyboardawarescrollview/MainActivity.kt +61 -0
  10. package/android/app/src/main/java/com/anonymous/reactnativeuniversalkeyboardawarescrollview/MainApplication.kt +56 -0
  11. package/android/app/src/main/res/drawable/ic_launcher_background.xml +6 -0
  12. package/android/app/src/main/res/drawable/rn_edit_text_material.xml +37 -0
  13. package/android/app/src/main/res/drawable-hdpi/splashscreen_logo.png +0 -0
  14. package/android/app/src/main/res/drawable-mdpi/splashscreen_logo.png +0 -0
  15. package/android/app/src/main/res/drawable-xhdpi/splashscreen_logo.png +0 -0
  16. package/android/app/src/main/res/drawable-xxhdpi/splashscreen_logo.png +0 -0
  17. package/android/app/src/main/res/drawable-xxxhdpi/splashscreen_logo.png +0 -0
  18. package/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +5 -0
  19. package/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +5 -0
  20. package/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp +0 -0
  21. package/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp +0 -0
  22. package/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp +0 -0
  23. package/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp +0 -0
  24. package/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp +0 -0
  25. package/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp +0 -0
  26. package/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp +0 -0
  27. package/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp +0 -0
  28. package/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp +0 -0
  29. package/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp +0 -0
  30. package/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp +0 -0
  31. package/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp +0 -0
  32. package/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp +0 -0
  33. package/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp +0 -0
  34. package/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp +0 -0
  35. package/android/app/src/main/res/values/colors.xml +6 -0
  36. package/android/app/src/main/res/values/strings.xml +5 -0
  37. package/android/app/src/main/res/values/styles.xml +11 -0
  38. package/android/app/src/main/res/values-night/colors.xml +1 -0
  39. package/android/build.gradle +89 -0
  40. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  41. package/android/gradle/wrapper/gradle-wrapper.properties +7 -0
  42. package/android/gradle.properties +65 -0
  43. package/android/gradlew +251 -0
  44. package/android/gradlew.bat +94 -0
  45. package/android/settings.gradle +39 -0
  46. package/android/src/main/AndroidManifest.xml +3 -0
  47. package/android/src/main/java/com/universalkeyboard/UniversalKeyboardModule.kt +349 -0
  48. package/android/src/main/java/com/universalkeyboard/UniversalKeyboardPackage.kt +21 -0
  49. package/ios/.xcode.env +11 -0
  50. package/ios/Podfile +60 -0
  51. package/ios/Podfile.lock +2001 -0
  52. package/ios/Podfile.properties.json +5 -0
  53. package/ios/UniversalKeyboard.h +24 -0
  54. package/ios/UniversalKeyboard.m +413 -0
  55. package/ios/reactnativeuniversalkeyboardawarescrollview/AppDelegate.swift +70 -0
  56. package/ios/reactnativeuniversalkeyboardawarescrollview/Images.xcassets/AppIcon.appiconset/App-Icon-1024x1024@1x.png +0 -0
  57. package/ios/reactnativeuniversalkeyboardawarescrollview/Images.xcassets/AppIcon.appiconset/Contents.json +14 -0
  58. package/ios/reactnativeuniversalkeyboardawarescrollview/Images.xcassets/Contents.json +6 -0
  59. package/ios/reactnativeuniversalkeyboardawarescrollview/Images.xcassets/SplashScreenBackground.colorset/Contents.json +20 -0
  60. package/ios/reactnativeuniversalkeyboardawarescrollview/Images.xcassets/SplashScreenLegacy.imageset/Contents.json +23 -0
  61. package/ios/reactnativeuniversalkeyboardawarescrollview/Images.xcassets/SplashScreenLegacy.imageset/image.png +0 -0
  62. package/ios/reactnativeuniversalkeyboardawarescrollview/Images.xcassets/SplashScreenLegacy.imageset/image@2x.png +0 -0
  63. package/ios/reactnativeuniversalkeyboardawarescrollview/Images.xcassets/SplashScreenLegacy.imageset/image@3x.png +0 -0
  64. package/ios/reactnativeuniversalkeyboardawarescrollview/Info.plist +76 -0
  65. package/ios/reactnativeuniversalkeyboardawarescrollview/PrivacyInfo.xcprivacy +48 -0
  66. package/ios/reactnativeuniversalkeyboardawarescrollview/SplashScreen.storyboard +48 -0
  67. package/ios/reactnativeuniversalkeyboardawarescrollview/Supporting/Expo.plist +12 -0
  68. package/ios/reactnativeuniversalkeyboardawarescrollview/reactnativeuniversalkeyboardawarescrollview-Bridging-Header.h +3 -0
  69. package/ios/reactnativeuniversalkeyboardawarescrollview/reactnativeuniversalkeyboardawarescrollview.entitlements +5 -0
  70. package/ios/reactnativeuniversalkeyboardawarescrollview.xcodeproj/project.pbxproj +540 -0
  71. package/ios/reactnativeuniversalkeyboardawarescrollview.xcodeproj/xcshareddata/xcschemes/reactnativeuniversalkeyboardawarescrollview.xcscheme +88 -0
  72. package/ios/reactnativeuniversalkeyboardawarescrollview.xcworkspace/contents.xcworkspacedata +10 -0
  73. package/package.json +61 -0
  74. package/react-native-universal-keyboard-aware-scrollview.podspec +32 -0
  75. package/react-native.config.js +18 -0
  76. package/src/NativeModule.ts +61 -0
  77. package/src/components/KeyboardAwareScrollView.tsx +388 -0
  78. package/src/components/index.ts +5 -0
  79. package/src/hooks/index.ts +2 -0
  80. package/src/hooks/useKeyboard.ts +360 -0
  81. package/src/index.ts +27 -0
  82. package/src/types.ts +87 -0
  83. package/src/utils/KeyboardController.ts +112 -0
  84. package/src/utils/index.ts +1 -0
@@ -0,0 +1,5 @@
1
+ {
2
+ "expo.jsEngine": "hermes",
3
+ "EX_DEV_CLIENT_NETWORK_INSPECTOR": "true",
4
+ "newArchEnabled": "true"
5
+ }
@@ -0,0 +1,24 @@
1
+ #import <React/RCTBridgeModule.h>
2
+ #import <React/RCTEventEmitter.h>
3
+
4
+ /**
5
+ * UniversalKeyboard - Native iOS module for detecting keyboard height changes.
6
+ *
7
+ * This module provides reliable keyboard detection that works in:
8
+ * - Normal React Native screens
9
+ * - React Native Modal components
10
+ * - BottomSheet components
11
+ * - Any overlay/presentation scenarios
12
+ *
13
+ * It uses UIKeyboardWillChangeFrameNotification which is the most reliable
14
+ * notification for keyboard changes on iOS, providing accurate frame
15
+ * information including during interactive dismissals and keyboard size
16
+ * changes.
17
+ */
18
+ @interface UniversalKeyboard : RCTEventEmitter <RCTBridgeModule>
19
+
20
+ @property(nonatomic, assign) BOOL hasListeners;
21
+ @property(nonatomic, assign) CGFloat lastKeyboardHeight;
22
+ @property(nonatomic, assign) BOOL isKeyboardVisible;
23
+
24
+ @end
@@ -0,0 +1,413 @@
1
+ #import "UniversalKeyboard.h"
2
+ #import <React/RCTLog.h>
3
+ #import <React/RCTUtils.h>
4
+ #import <UIKit/UIKit.h>
5
+
6
+ @implementation UniversalKeyboard
7
+
8
+ RCT_EXPORT_MODULE();
9
+
10
+ #pragma mark - Initialization
11
+
12
+ - (instancetype)init {
13
+ self = [super init];
14
+ if (self) {
15
+ _hasListeners = NO;
16
+ _lastKeyboardHeight = 0;
17
+ _isKeyboardVisible = NO;
18
+ }
19
+ return self;
20
+ }
21
+
22
+ - (void)dealloc {
23
+ [self removeKeyboardObservers];
24
+ }
25
+
26
+ #pragma mark - RCTEventEmitter
27
+
28
+ + (BOOL)requiresMainQueueSetup {
29
+ return YES;
30
+ }
31
+
32
+ - (NSArray<NSString *> *)supportedEvents {
33
+ return @[
34
+ @"keyboardDidShow", @"keyboardDidHide", @"keyboardHeightChanged",
35
+ @"keyboardWillShow", @"keyboardWillHide"
36
+ ];
37
+ }
38
+
39
+ - (void)startObserving {
40
+ _hasListeners = YES;
41
+ }
42
+
43
+ - (void)stopObserving {
44
+ _hasListeners = NO;
45
+ }
46
+
47
+ #pragma mark - Public Methods
48
+
49
+ /**
50
+ * Start listening for keyboard events.
51
+ * This method MUST be called from JS before keyboard events will be emitted.
52
+ */
53
+ RCT_EXPORT_METHOD(startListening : (RCTPromiseResolveBlock)
54
+ resolve rejecter : (RCTPromiseRejectBlock)reject) {
55
+ dispatch_async(dispatch_get_main_queue(), ^{
56
+ @try {
57
+ [self setupKeyboardObservers];
58
+ resolve(@YES);
59
+ } @catch (NSException *exception) {
60
+ reject(
61
+ @"ERROR",
62
+ [NSString stringWithFormat:@"Failed to start keyboard listener: %@",
63
+ exception.reason],
64
+ nil);
65
+ }
66
+ });
67
+ }
68
+
69
+ /**
70
+ * Stop listening for keyboard events.
71
+ * Call this when the component unmounts to prevent issues.
72
+ */
73
+ RCT_EXPORT_METHOD(stopListening : (RCTPromiseResolveBlock)
74
+ resolve rejecter : (RCTPromiseRejectBlock)reject) {
75
+ dispatch_async(dispatch_get_main_queue(), ^{
76
+ @try {
77
+ [self removeKeyboardObservers];
78
+ resolve(@YES);
79
+ } @catch (NSException *exception) {
80
+ reject(@"ERROR",
81
+ [NSString stringWithFormat:@"Failed to stop keyboard listener: %@",
82
+ exception.reason],
83
+ nil);
84
+ }
85
+ });
86
+ }
87
+
88
+ /**
89
+ * Get the current keyboard height.
90
+ */
91
+ RCT_EXPORT_METHOD(getKeyboardHeight : (RCTPromiseResolveBlock)
92
+ resolve rejecter : (RCTPromiseRejectBlock)reject) {
93
+ resolve(@(self.lastKeyboardHeight));
94
+ }
95
+
96
+ /**
97
+ * Check if the keyboard is currently visible.
98
+ */
99
+ RCT_EXPORT_METHOD(isKeyboardVisible : (RCTPromiseResolveBlock)
100
+ resolve rejecter : (RCTPromiseRejectBlock)reject) {
101
+ resolve(@(self.isKeyboardVisible));
102
+ }
103
+
104
+ /**
105
+ * Force dismiss the keyboard.
106
+ */
107
+ RCT_EXPORT_METHOD(dismissKeyboard : (RCTPromiseResolveBlock)
108
+ resolve rejecter : (RCTPromiseRejectBlock)reject) {
109
+ dispatch_async(dispatch_get_main_queue(), ^{
110
+ @try {
111
+ UIWindow *window = [self getKeyWindow];
112
+ if (window) {
113
+ [window endEditing:YES];
114
+ }
115
+ resolve(@YES);
116
+ } @catch (NSException *exception) {
117
+ reject(@"ERROR",
118
+ [NSString stringWithFormat:@"Failed to dismiss keyboard: %@",
119
+ exception.reason],
120
+ nil);
121
+ }
122
+ });
123
+ }
124
+
125
+ #pragma mark - Keyboard Observers
126
+
127
+ /**
128
+ * Sets up observers for keyboard notifications.
129
+ * Uses multiple notifications for comprehensive keyboard tracking.
130
+ */
131
+ - (void)setupKeyboardObservers {
132
+ // Remove existing observers first
133
+ [self removeKeyboardObservers];
134
+
135
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
136
+
137
+ // Main notification - provides frame information for all keyboard changes
138
+ [center addObserver:self
139
+ selector:@selector(keyboardWillChangeFrame:)
140
+ name:UIKeyboardWillChangeFrameNotification
141
+ object:nil];
142
+
143
+ // Additional notifications for will show/hide
144
+ [center addObserver:self
145
+ selector:@selector(keyboardWillShow:)
146
+ name:UIKeyboardWillShowNotification
147
+ object:nil];
148
+
149
+ [center addObserver:self
150
+ selector:@selector(keyboardWillHide:)
151
+ name:UIKeyboardWillHideNotification
152
+ object:nil];
153
+
154
+ // Did show/hide for confirmation
155
+ [center addObserver:self
156
+ selector:@selector(keyboardDidShow:)
157
+ name:UIKeyboardDidShowNotification
158
+ object:nil];
159
+
160
+ [center addObserver:self
161
+ selector:@selector(keyboardDidHide:)
162
+ name:UIKeyboardDidHideNotification
163
+ object:nil];
164
+ }
165
+
166
+ /**
167
+ * Removes all keyboard observers to prevent memory leaks.
168
+ */
169
+ - (void)removeKeyboardObservers {
170
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
171
+ }
172
+
173
+ #pragma mark - Keyboard Notification Handlers
174
+
175
+ /**
176
+ * Handler for UIKeyboardWillChangeFrameNotification.
177
+ * This is the most reliable notification for keyboard frame changes.
178
+ */
179
+ - (void)keyboardWillChangeFrame:(NSNotification *)notification {
180
+ if (!self.hasListeners)
181
+ return;
182
+
183
+ NSDictionary *userInfo = notification.userInfo;
184
+ if (!userInfo)
185
+ return;
186
+
187
+ CGRect beginFrame = [userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue];
188
+ CGRect endFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
189
+ NSTimeInterval duration =
190
+ [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
191
+ UIViewAnimationCurve curve =
192
+ [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
193
+
194
+ // Calculate keyboard height
195
+ CGFloat keyboardHeight = [self calculateKeyboardHeightFromFrame:endFrame];
196
+
197
+ // Emit height change event
198
+ if (keyboardHeight != self.lastKeyboardHeight) {
199
+ self.lastKeyboardHeight = keyboardHeight;
200
+
201
+ [self sendEventWithName:@"keyboardHeightChanged"
202
+ body:[self createEventDataWithHeight:keyboardHeight
203
+ duration:duration
204
+ curve:curve
205
+ beginFrame:beginFrame
206
+ endFrame:endFrame]];
207
+ }
208
+ }
209
+
210
+ /**
211
+ * Handler for UIKeyboardWillShowNotification.
212
+ */
213
+ - (void)keyboardWillShow:(NSNotification *)notification {
214
+ if (!self.hasListeners)
215
+ return;
216
+
217
+ NSDictionary *userInfo = notification.userInfo;
218
+ CGRect endFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
219
+ NSTimeInterval duration =
220
+ [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
221
+ UIViewAnimationCurve curve =
222
+ [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
223
+
224
+ CGFloat keyboardHeight = [self calculateKeyboardHeightFromFrame:endFrame];
225
+
226
+ [self sendEventWithName:@"keyboardWillShow"
227
+ body:[self createEventDataWithHeight:keyboardHeight
228
+ duration:duration
229
+ curve:curve
230
+ beginFrame:CGRectZero
231
+ endFrame:endFrame]];
232
+ }
233
+
234
+ /**
235
+ * Handler for UIKeyboardWillHideNotification.
236
+ */
237
+ - (void)keyboardWillHide:(NSNotification *)notification {
238
+ if (!self.hasListeners)
239
+ return;
240
+
241
+ NSDictionary *userInfo = notification.userInfo;
242
+ NSTimeInterval duration =
243
+ [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
244
+ UIViewAnimationCurve curve =
245
+ [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue];
246
+
247
+ [self sendEventWithName:@"keyboardWillHide"
248
+ body:[self createEventDataWithHeight:0
249
+ duration:duration
250
+ curve:curve
251
+ beginFrame:CGRectZero
252
+ endFrame:CGRectZero]];
253
+ }
254
+
255
+ /**
256
+ * Handler for UIKeyboardDidShowNotification.
257
+ */
258
+ - (void)keyboardDidShow:(NSNotification *)notification {
259
+ if (!self.hasListeners)
260
+ return;
261
+
262
+ self.isKeyboardVisible = YES;
263
+
264
+ NSDictionary *userInfo = notification.userInfo;
265
+ CGRect endFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
266
+ CGFloat keyboardHeight = [self calculateKeyboardHeightFromFrame:endFrame];
267
+
268
+ self.lastKeyboardHeight = keyboardHeight;
269
+
270
+ [self sendEventWithName:@"keyboardDidShow"
271
+ body:[self createEventDataWithHeight:keyboardHeight
272
+ duration:0
273
+ curve:0
274
+ beginFrame:CGRectZero
275
+ endFrame:endFrame]];
276
+ }
277
+
278
+ /**
279
+ * Handler for UIKeyboardDidHideNotification.
280
+ */
281
+ - (void)keyboardDidHide:(NSNotification *)notification {
282
+ if (!self.hasListeners)
283
+ return;
284
+
285
+ self.isKeyboardVisible = NO;
286
+ self.lastKeyboardHeight = 0;
287
+
288
+ [self sendEventWithName:@"keyboardDidHide"
289
+ body:[self createEventDataWithHeight:0
290
+ duration:0
291
+ curve:0
292
+ beginFrame:CGRectZero
293
+ endFrame:CGRectZero]];
294
+ }
295
+
296
+ #pragma mark - Helper Methods
297
+
298
+ /**
299
+ * Calculates the keyboard height from keyboard frame.
300
+ * Accounts for safe area on notch devices.
301
+ */
302
+ - (CGFloat)calculateKeyboardHeightFromFrame:(CGRect)frame {
303
+ CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
304
+
305
+ // If the keyboard frame extends beyond the screen, it's hidden
306
+ if (frame.origin.y >= screenHeight) {
307
+ return 0;
308
+ }
309
+
310
+ // Calculate keyboard height
311
+ CGFloat keyboardHeight = screenHeight - frame.origin.y;
312
+
313
+ // For modals and presented view controllers, we need to check
314
+ // if the keyboard is actually visible
315
+ if (keyboardHeight <= 0) {
316
+ return 0;
317
+ }
318
+
319
+ return keyboardHeight;
320
+ }
321
+
322
+ /**
323
+ * Gets the safe area bottom inset for proper keyboard height calculation.
324
+ */
325
+ - (CGFloat)getSafeAreaBottomInset {
326
+ UIWindow *window = [self getKeyWindow];
327
+ if (@available(iOS 11.0, *)) {
328
+ if (window) {
329
+ return window.safeAreaInsets.bottom;
330
+ }
331
+ }
332
+ return 0;
333
+ }
334
+
335
+ /**
336
+ * Gets the key window (works on iOS 13+ and earlier).
337
+ */
338
+ - (UIWindow *)getKeyWindow {
339
+ if (@available(iOS 13.0, *)) {
340
+ for (UIWindowScene *scene in [UIApplication sharedApplication]
341
+ .connectedScenes) {
342
+ if (scene.activationState == UISceneActivationStateForegroundActive) {
343
+ for (UIWindow *window in scene.windows) {
344
+ if (window.isKeyWindow) {
345
+ return window;
346
+ }
347
+ }
348
+ }
349
+ }
350
+ }
351
+
352
+ // Fallback for iOS < 13
353
+ #pragma clang diagnostic push
354
+ #pragma clang diagnostic ignored "-Wdeprecated-declarations"
355
+ return [UIApplication sharedApplication].keyWindow;
356
+ #pragma clang diagnostic pop
357
+ }
358
+
359
+ /**
360
+ * Creates the event data dictionary for keyboard events.
361
+ */
362
+ - (NSDictionary *)createEventDataWithHeight:(CGFloat)height
363
+ duration:(NSTimeInterval)duration
364
+ curve:(UIViewAnimationCurve)curve
365
+ beginFrame:(CGRect)beginFrame
366
+ endFrame:(CGRect)endFrame {
367
+ CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
368
+ CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
369
+ CGFloat safeAreaBottom = [self getSafeAreaBottomInset];
370
+
371
+ return @{
372
+ @"height" : @(height),
373
+ @"isVisible" : @(height > 0),
374
+ @"duration" : @(duration * 1000), // Convert to milliseconds
375
+ @"easing" : [self easingFromCurve:curve],
376
+ @"screenHeight" : @(screenHeight),
377
+ @"screenWidth" : @(screenWidth),
378
+ @"safeAreaBottom" : @(safeAreaBottom),
379
+ @"endCoordinates" : @{
380
+ @"screenX" : @(endFrame.origin.x),
381
+ @"screenY" : @(endFrame.origin.y),
382
+ @"width" : @(endFrame.size.width),
383
+ @"height" : @(endFrame.size.height)
384
+ },
385
+ @"startCoordinates" : @{
386
+ @"screenX" : @(beginFrame.origin.x),
387
+ @"screenY" : @(beginFrame.origin.y),
388
+ @"width" : @(beginFrame.size.width),
389
+ @"height" : @(beginFrame.size.height)
390
+ },
391
+ @"timestamp" : @([[NSDate date] timeIntervalSince1970] * 1000)
392
+ };
393
+ }
394
+
395
+ /**
396
+ * Converts UIViewAnimationCurve to a string identifier.
397
+ */
398
+ - (NSString *)easingFromCurve:(UIViewAnimationCurve)curve {
399
+ switch (curve) {
400
+ case UIViewAnimationCurveEaseIn:
401
+ return @"easeIn";
402
+ case UIViewAnimationCurveEaseOut:
403
+ return @"easeOut";
404
+ case UIViewAnimationCurveEaseInOut:
405
+ return @"easeInOut";
406
+ case UIViewAnimationCurveLinear:
407
+ return @"linear";
408
+ default:
409
+ return @"keyboard"; // iOS keyboard uses a custom curve (7)
410
+ }
411
+ }
412
+
413
+ @end
@@ -0,0 +1,70 @@
1
+ import Expo
2
+ import React
3
+ import ReactAppDependencyProvider
4
+
5
+ @UIApplicationMain
6
+ public class AppDelegate: ExpoAppDelegate {
7
+ var window: UIWindow?
8
+
9
+ var reactNativeDelegate: ExpoReactNativeFactoryDelegate?
10
+ var reactNativeFactory: RCTReactNativeFactory?
11
+
12
+ public override func application(
13
+ _ application: UIApplication,
14
+ didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
15
+ ) -> Bool {
16
+ let delegate = ReactNativeDelegate()
17
+ let factory = ExpoReactNativeFactory(delegate: delegate)
18
+ delegate.dependencyProvider = RCTAppDependencyProvider()
19
+
20
+ reactNativeDelegate = delegate
21
+ reactNativeFactory = factory
22
+ bindReactNativeFactory(factory)
23
+
24
+ #if os(iOS) || os(tvOS)
25
+ window = UIWindow(frame: UIScreen.main.bounds)
26
+ factory.startReactNative(
27
+ withModuleName: "main",
28
+ in: window,
29
+ launchOptions: launchOptions)
30
+ #endif
31
+
32
+ return super.application(application, didFinishLaunchingWithOptions: launchOptions)
33
+ }
34
+
35
+ // Linking API
36
+ public override func application(
37
+ _ app: UIApplication,
38
+ open url: URL,
39
+ options: [UIApplication.OpenURLOptionsKey: Any] = [:]
40
+ ) -> Bool {
41
+ return super.application(app, open: url, options: options) || RCTLinkingManager.application(app, open: url, options: options)
42
+ }
43
+
44
+ // Universal Links
45
+ public override func application(
46
+ _ application: UIApplication,
47
+ continue userActivity: NSUserActivity,
48
+ restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
49
+ ) -> Bool {
50
+ let result = RCTLinkingManager.application(application, continue: userActivity, restorationHandler: restorationHandler)
51
+ return super.application(application, continue: userActivity, restorationHandler: restorationHandler) || result
52
+ }
53
+ }
54
+
55
+ class ReactNativeDelegate: ExpoReactNativeFactoryDelegate {
56
+ // Extension point for config-plugins
57
+
58
+ override func sourceURL(for bridge: RCTBridge) -> URL? {
59
+ // needed to return the correct URL for expo-dev-client.
60
+ bridge.bundleURL ?? bundleURL()
61
+ }
62
+
63
+ override func bundleURL() -> URL? {
64
+ #if DEBUG
65
+ return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: ".expo/.virtual-metro-entry")
66
+ #else
67
+ return Bundle.main.url(forResource: "main", withExtension: "jsbundle")
68
+ #endif
69
+ }
70
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "images": [
3
+ {
4
+ "filename": "App-Icon-1024x1024@1x.png",
5
+ "idiom": "universal",
6
+ "platform": "ios",
7
+ "size": "1024x1024"
8
+ }
9
+ ],
10
+ "info": {
11
+ "version": 1,
12
+ "author": "expo"
13
+ }
14
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "info" : {
3
+ "version" : 1,
4
+ "author" : "expo"
5
+ }
6
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "colors": [
3
+ {
4
+ "color": {
5
+ "components": {
6
+ "alpha": "1.000",
7
+ "blue": "1.00000000000000",
8
+ "green": "1.00000000000000",
9
+ "red": "1.00000000000000"
10
+ },
11
+ "color-space": "srgb"
12
+ },
13
+ "idiom": "universal"
14
+ }
15
+ ],
16
+ "info": {
17
+ "version": 1,
18
+ "author": "expo"
19
+ }
20
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "images": [
3
+ {
4
+ "idiom": "universal",
5
+ "filename": "image.png",
6
+ "scale": "1x"
7
+ },
8
+ {
9
+ "idiom": "universal",
10
+ "filename": "image@2x.png",
11
+ "scale": "2x"
12
+ },
13
+ {
14
+ "idiom": "universal",
15
+ "filename": "image@3x.png",
16
+ "scale": "3x"
17
+ }
18
+ ],
19
+ "info": {
20
+ "version": 1,
21
+ "author": "expo"
22
+ }
23
+ }
@@ -0,0 +1,76 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>CADisableMinimumFrameDurationOnPhone</key>
6
+ <true/>
7
+ <key>CFBundleDevelopmentRegion</key>
8
+ <string>$(DEVELOPMENT_LANGUAGE)</string>
9
+ <key>CFBundleDisplayName</key>
10
+ <string>react-native-universal-keyboard-aware-scrollview</string>
11
+ <key>CFBundleExecutable</key>
12
+ <string>$(EXECUTABLE_NAME)</string>
13
+ <key>CFBundleIdentifier</key>
14
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
15
+ <key>CFBundleInfoDictionaryVersion</key>
16
+ <string>6.0</string>
17
+ <key>CFBundleName</key>
18
+ <string>$(PRODUCT_NAME)</string>
19
+ <key>CFBundlePackageType</key>
20
+ <string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
21
+ <key>CFBundleShortVersionString</key>
22
+ <string>1.0.0</string>
23
+ <key>CFBundleSignature</key>
24
+ <string>????</string>
25
+ <key>CFBundleURLTypes</key>
26
+ <array>
27
+ <dict>
28
+ <key>CFBundleURLSchemes</key>
29
+ <array>
30
+ <string>com.anonymous.reactnativeuniversalkeyboardawarescrollview</string>
31
+ </array>
32
+ </dict>
33
+ </array>
34
+ <key>CFBundleVersion</key>
35
+ <string>1</string>
36
+ <key>LSMinimumSystemVersion</key>
37
+ <string>12.0</string>
38
+ <key>LSRequiresIPhoneOS</key>
39
+ <true/>
40
+ <key>NSAppTransportSecurity</key>
41
+ <dict>
42
+ <key>NSAllowsArbitraryLoads</key>
43
+ <false/>
44
+ <key>NSAllowsLocalNetworking</key>
45
+ <true/>
46
+ </dict>
47
+ <key>RCTNewArchEnabled</key>
48
+ <true/>
49
+ <key>UILaunchStoryboardName</key>
50
+ <string>SplashScreen</string>
51
+ <key>UIRequiredDeviceCapabilities</key>
52
+ <array>
53
+ <string>arm64</string>
54
+ </array>
55
+ <key>UIRequiresFullScreen</key>
56
+ <false/>
57
+ <key>UIStatusBarStyle</key>
58
+ <string>UIStatusBarStyleDefault</string>
59
+ <key>UISupportedInterfaceOrientations</key>
60
+ <array>
61
+ <string>UIInterfaceOrientationPortrait</string>
62
+ <string>UIInterfaceOrientationPortraitUpsideDown</string>
63
+ </array>
64
+ <key>UISupportedInterfaceOrientations~ipad</key>
65
+ <array>
66
+ <string>UIInterfaceOrientationPortrait</string>
67
+ <string>UIInterfaceOrientationPortraitUpsideDown</string>
68
+ <string>UIInterfaceOrientationLandscapeLeft</string>
69
+ <string>UIInterfaceOrientationLandscapeRight</string>
70
+ </array>
71
+ <key>UIUserInterfaceStyle</key>
72
+ <string>Light</string>
73
+ <key>UIViewControllerBasedStatusBarAppearance</key>
74
+ <false/>
75
+ </dict>
76
+ </plist>