Browse Source

feat(iOS): Add prop autoManageStatusBarEnabled (#914)

Co-authored-by: Jamon Holmgren <jamon@infinite.red>
Co-authored-by: Jamon Holmgren <jamonholmgren@gmail.com>
Co-authored-by: Thibault Malbranche <thibault.malbranche@epitech.eu>
Kesha Antonov 3 years ago
parent
commit
22a60fd23a
No account linked to committer's email address
5 changed files with 91 additions and 54 deletions
  1. 1
    0
      apple/RNCWebView.h
  2. 10
    2
      apple/RNCWebView.m
  3. 1
    0
      apple/RNCWebViewManager.m
  4. 71
    52
      docs/Reference.md
  5. 8
    0
      src/WebViewTypes.ts

+ 1
- 0
apple/RNCWebView.h View File

@@ -35,6 +35,7 @@
35 35
 @property (nonatomic, assign) BOOL injectedJavaScriptBeforeContentLoadedForMainFrameOnly;
36 36
 @property (nonatomic, assign) BOOL scrollEnabled;
37 37
 @property (nonatomic, assign) BOOL sharedCookiesEnabled;
38
+@property (nonatomic, assign) BOOL autoManageStatusBarEnabled;
38 39
 @property (nonatomic, assign) BOOL pagingEnabled;
39 40
 @property (nonatomic, assign) CGFloat decelerationRate;
40 41
 @property (nonatomic, assign) BOOL allowsInlineMediaPlayback;

+ 10
- 2
apple/RNCWebView.m View File

@@ -125,6 +125,7 @@ static NSDictionary* customCertificatesForHost;
125 125
     _showsVerticalScrollIndicator = YES;
126 126
     _directionalLockEnabled = YES;
127 127
     _automaticallyAdjustContentInsets = YES;
128
+    _autoManageStatusBarEnabled = YES;
128 129
     _contentInset = UIEdgeInsetsZero;
129 130
     _savedKeyboardDisplayRequiresUserAction = YES;
130 131
     #if !TARGET_OS_OSX
@@ -335,9 +336,13 @@ static NSDictionary* customCertificatesForHost;
335 336
 -(void)showFullScreenVideoStatusBars
336 337
 {
337 338
 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
339
+    if (!_autoManageStatusBarEnabled) {
340
+      return;
341
+    }
342
+
338 343
     _isFullScreenVideoOpen = YES;
339 344
     RCTUnsafeExecuteOnMainQueueSync(^{
340
-      [RCTSharedApplication() setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];
345
+      [RCTSharedApplication() setStatusBarStyle:self->_savedStatusBarStyle animated:YES];
341 346
     });
342 347
 #pragma clang diagnostic pop
343 348
 }
@@ -345,6 +350,10 @@ static NSDictionary* customCertificatesForHost;
345 350
 -(void)hideFullScreenVideoStatusBars
346 351
 {
347 352
 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
353
+    if (!_autoManageStatusBarEnabled) {
354
+      return;
355
+    }
356
+
348 357
     _isFullScreenVideoOpen = NO;
349 358
     RCTUnsafeExecuteOnMainQueueSync(^{
350 359
       [RCTSharedApplication() setStatusBarHidden:self->_savedStatusBarHidden animated:YES];
@@ -1375,4 +1384,3 @@ static NSDictionary* customCertificatesForHost;
1375 1384
 }
1376 1385
 
1377 1386
 @end
1378
-

+ 1
- 0
apple/RNCWebViewManager.m View File

@@ -66,6 +66,7 @@ RCT_EXPORT_VIEW_PROPERTY(dataDetectorTypes, WKDataDetectorTypes)
66 66
 #endif
67 67
 RCT_EXPORT_VIEW_PROPERTY(contentInset, UIEdgeInsets)
68 68
 RCT_EXPORT_VIEW_PROPERTY(automaticallyAdjustContentInsets, BOOL)
69
+RCT_EXPORT_VIEW_PROPERTY(autoManageStatusBarEnabled, BOOL)
69 70
 RCT_EXPORT_VIEW_PROPERTY(hideKeyboardAccessoryView, BOOL)
70 71
 RCT_EXPORT_VIEW_PROPERTY(allowsBackForwardNavigationGestures, BOOL)
71 72
 RCT_EXPORT_VIEW_PROPERTY(incognito, BOOL)

+ 71
- 52
docs/Reference.md View File

@@ -71,6 +71,7 @@ This document lays out the current public properties and methods for the React N
71 71
 - [`pullToRefreshEnabled`](Reference.md#pullToRefreshEnabled)
72 72
 - [`ignoreSilentHardwareSwitch`](Reference.md#ignoreSilentHardwareSwitch)
73 73
 - [`onFileDownload`](Reference.md#onFileDownload)
74
+- [`autoManageStatusBarEnabled`](Reference.md#autoManageStatusBarEnabled)
74 75
 
75 76
 ## Methods Index
76 77
 
@@ -136,9 +137,9 @@ Make sure the string evaluates to a valid type (`true` works) and doesn't otherw
136 137
 
137 138
 On iOS, see [`WKUserScriptInjectionTimeAtDocumentEnd`](https://developer.apple.com/documentation/webkit/wkuserscriptinjectiontime/wkuserscriptinjectiontimeatdocumentend?language=objc)
138 139
 
139
-| Type   | Required | Platform |
140
-| ------ | -------- | -------- |
141
-| string | No       | iOS, Android, macOS
140
+| Type   | Required | Platform            |
141
+| ------ | -------- | ------------------- |
142
+| string | No       | iOS, Android, macOS |
142 143
 
143 144
 To learn more, read the [Communicating between JS and Native](Guide.md#communicating-between-js-and-native) guide.
144 145
 
@@ -168,15 +169,15 @@ Make sure the string evaluates to a valid type (`true` works) and doesn't otherw
168 169
 
169 170
 On iOS, see [`WKUserScriptInjectionTimeAtDocumentStart`](https://developer.apple.com/documentation/webkit/wkuserscriptinjectiontime/wkuserscriptinjectiontimeatdocumentstart?language=objc)
170 171
 
171
-| Type   | Required | Platform |
172
-| ------ | -------- | -------- |
172
+| Type   | Required | Platform   |
173
+| ------ | -------- | ---------- |
173 174
 | string | No       | iOS, macOS |
174 175
 
175 176
 To learn more, read the [Communicating between JS and Native](Guide.md#communicating-between-js-and-native) guide.
176 177
 
177 178
 Example:
178 179
 
179
-Post message a JSON object of `window.location` to be handled by [`onMessage`](Reference.md#onmessage). `window.ReactNativeWebView.postMessage` *will* be available at this time.
180
+Post message a JSON object of `window.location` to be handled by [`onMessage`](Reference.md#onmessage). `window.ReactNativeWebView.postMessage` _will_ be available at this time.
180 181
 
181 182
 ```jsx
182 183
 const INJECTED_JAVASCRIPT = `(function() {
@@ -198,8 +199,8 @@ If `true` (default; mandatory for Android), loads the `injectedJavaScript` only
198 199
 
199 200
 If `false`, (only supported on iOS and macOS), loads it into all frames (e.g. iframes).
200 201
 
201
-| Type   | Required | Platform |
202
-| ------ | -------- | -------- |
202
+| Type | Required | Platform                                          |
203
+| ---- | -------- | ------------------------------------------------- |
203 204
 | bool | No       | iOS and macOS (only `true` supported for Android) |
204 205
 
205 206
 ---
@@ -210,8 +211,8 @@ If `true` (default; mandatory for Android), loads the `injectedJavaScriptBeforeC
210 211
 
211 212
 If `false`, (only supported on iOS and macOS), loads it into all frames (e.g. iframes).
212 213
 
213
-| Type   | Required | Platform |
214
-| ------ | -------- | -------- |
214
+| Type | Required | Platform                                          |
215
+| ---- | -------- | ------------------------------------------------- |
215 216
 | bool | No       | iOS and macOS (only `true` supported for Android) |
216 217
 
217 218
 ---
@@ -222,8 +223,8 @@ Boolean that determines whether HTML5 audio and video requires the user to tap t
222 223
 
223 224
 NOTE: the default `true` value might cause some videos to hang loading on iOS. Setting it to `false` could fix this issue.
224 225
 
225
-| Type | Required | Platform |
226
-| ---- | -------- | -------- |
226
+| Type | Required | Platform            |
227
+| ---- | -------- | ------------------- |
227 228
 | bool | No       | iOS, Android, macOS |
228 229
 
229 230
 ---
@@ -238,8 +239,8 @@ The `nativeConfig` prop expects an object with the following keys:
238 239
 - `props` (object)
239 240
 - `viewManager` (object)
240 241
 
241
-| Type   | Required | Platform |
242
-| ------ | -------- | -------- |
242
+| Type   | Required | Platform            |
243
+| ------ | -------- | ------------------- |
243 244
 | object | No       | iOS, Android, macOS |
244 245
 
245 246
 ---
@@ -257,7 +258,7 @@ Example:
257 258
 ```jsx
258 259
 <WebView
259 260
   source={{ uri: 'https://reactnative.dev' }}
260
-  onError={syntheticEvent => {
261
+  onError={(syntheticEvent) => {
261 262
     const { nativeEvent } = syntheticEvent;
262 263
     console.warn('WebView error: ', nativeEvent);
263 264
   }}
@@ -297,7 +298,7 @@ Example:
297 298
 ```jsx
298 299
 <WebView
299 300
   source={{ uri: 'https://reactnative.dev' }}
300
-  onLoad={syntheticEvent => {
301
+  onLoad={(syntheticEvent) => {
301 302
     const { nativeEvent } = syntheticEvent;
302 303
     this.url = nativeEvent.url;
303 304
   }}
@@ -330,7 +331,7 @@ Example:
330 331
 ```jsx
331 332
 <WebView
332 333
   source={{ uri: 'https://reactnative.dev' }}
333
-  onLoadEnd={syntheticEvent => {
334
+  onLoadEnd={(syntheticEvent) => {
334 335
     // update component to be aware of loading status
335 336
     const { nativeEvent } = syntheticEvent;
336 337
     this.isLoading = nativeEvent.loading;
@@ -364,7 +365,7 @@ Example:
364 365
 ```jsx
365 366
 <WebView
366 367
   source={{ uri: 'https://reactnative.dev/=' }}
367
-  onLoadStart={syntheticEvent => {
368
+  onLoadStart={(syntheticEvent) => {
368 369
     // update component to be aware of loading status
369 370
     const { nativeEvent } = syntheticEvent;
370 371
     this.isLoading = nativeEvent.loading;
@@ -389,8 +390,8 @@ url
389 390
 
390 391
 Function that is invoked when the `WebView` is loading.
391 392
 
392
-| Type     | Required | Platform |
393
-| -------- | -------- | --------- |
393
+| Type     | Required | Platform            |
394
+| -------- | -------- | ------------------- |
394 395
 | function | No       | iOS, Android, macOS |
395 396
 
396 397
 Example:
@@ -434,7 +435,7 @@ Example:
434 435
 ```jsx
435 436
 <WebView
436 437
   source={{ uri: 'https://reactnative.dev' }}
437
-  onHttpError={syntheticEvent => {
438
+  onHttpError={(syntheticEvent) => {
438 439
     const { nativeEvent } = syntheticEvent;
439 440
     console.warn(
440 441
       'WebView received error status code: ',
@@ -522,7 +523,7 @@ Example:
522 523
 ```jsx
523 524
 <WebView
524 525
   source={{ uri: 'https://reactnative.dev' }}
525
-  onNavigationStateChange={navState => {
526
+  onNavigationStateChange={(navState) => {
526 527
     // Keep track of going back navigation within component
527 528
     this.canGoBack = navState.canGoBack;
528 529
   }}
@@ -556,7 +557,7 @@ Example:
556 557
 ```jsx
557 558
 <WebView
558 559
   source={{ uri: 'https://reactnative.dev' }}
559
-  onContentProcessDidTerminate={syntheticEvent => {
560
+  onContentProcessDidTerminate={(syntheticEvent) => {
560 561
     const { nativeEvent } = syntheticEvent;
561 562
     console.warn('Content process terminated, reloading', nativeEvent);
562 563
     this.refs.webview.reload();
@@ -581,8 +582,8 @@ url
581 582
 
582 583
 List of origin strings to allow being navigated to. The strings allow wildcards and get matched against _just_ the origin (not the full URL). If the user taps to navigate to a new page but the new page is not in this whitelist, the URL will be handled by the OS. The default whitelisted origins are "http://*" and "https://*".
583 584
 
584
-| Type             | Required | Platform |
585
-| ---------------- | -------- | -------- |
585
+| Type             | Required | Platform            |
586
+| ---------------- | -------- | ------------------- |
586 587
 | array of strings | No       | iOS, Android, macOS |
587 588
 
588 589
 Example:
@@ -601,8 +602,8 @@ Example:
601 602
 
602 603
 Function that returns a view to show if there's an error.
603 604
 
604
-| Type     | Required | Platform |
605
-| -------- | -------- | -------- |
605
+| Type     | Required | Platform            |
606
+| -------- | -------- | ------------------- |
606 607
 | function | No       | iOS, Android, macOS |
607 608
 
608 609
 Example:
@@ -610,7 +611,7 @@ Example:
610 611
 ```jsx
611 612
 <WebView
612 613
   source={{ uri: 'https://reactnative.dev' }}
613
-  renderError={errorName => <Error name={errorName} />}
614
+  renderError={(errorName) => <Error name={errorName} />}
614 615
 />
615 616
 ```
616 617
 
@@ -622,8 +623,8 @@ The function passed to `renderError` will be called with the name of the error
622 623
 
623 624
 Function that returns a loading indicator. The startInLoadingState prop must be set to true in order to use this prop.
624 625
 
625
-| Type     | Required | Platform |
626
-| -------- | -------- | -------- |
626
+| Type     | Required | Platform            |
627
+| -------- | -------- | ------------------- |
627 628
 | function | No       | iOS, Android, macOS |
628 629
 
629 630
 Example:
@@ -654,8 +655,8 @@ Function that allows custom handling of any web view requests. Return `true` fro
654 655
 
655 656
 On Android, is not called on the first load.
656 657
 
657
-| Type     | Required | Platform |
658
-| -------- | -------- | -------- |
658
+| Type     | Required | Platform            |
659
+| -------- | -------- | ------------------- |
659 660
 | function | No       | iOS, Android, macOS |
660 661
 
661 662
 Example:
@@ -663,7 +664,7 @@ Example:
663 664
 ```jsx
664 665
 <WebView
665 666
   source={{ uri: 'https://reactnative.dev' }}
666
-  onShouldStartLoadWithRequest={request => {
667
+  onShouldStartLoadWithRequest={(request) => {
667 668
     // Only allow navigating within this website
668 669
     return request.url.startsWith('https://reactnative.dev');
669 670
   }}
@@ -691,8 +692,8 @@ isTopFrame
691 692
 
692 693
 Boolean value that forces the `WebView` to show the loading view on the first load. This prop must be set to `true` in order for the `renderLoading` prop to work.
693 694
 
694
-| Type | Required | Platform |
695
-| ---- | -------- | -------- |
695
+| Type | Required | Platform            |
696
+| ---- | -------- | ------------------- |
696 697
 | bool | No       | iOS, Android, macOS |
697 698
 
698 699
 ---
@@ -836,8 +837,8 @@ Boolean value to enable third party cookies in the `WebView`. Used on Android Lo
836 837
 
837 838
 Sets the user-agent for the `WebView`.
838 839
 
839
-| Type   | Required | Platform |
840
-| ------ | -------- | -------- |
840
+| Type   | Required | Platform            |
841
+| ------ | -------- | ------------------- |
841 842
 | string | No       | iOS, Android, macOS |
842 843
 
843 844
 ---
@@ -846,8 +847,8 @@ Sets the user-agent for the `WebView`.
846 847
 
847 848
 Append to the existing user-agent. Setting `userAgent` will override this.
848 849
 
849
-| Type   | Required | Platform |
850
-| ------ | -------- | -------- |
850
+| Type   | Required | Platform            |
851
+| ------ | -------- | ------------------- |
851 852
 | string | No       | iOS, Android, macOS |
852 853
 
853 854
 ```jsx
@@ -1004,8 +1005,8 @@ The default value is `true`.
1004 1005
 
1005 1006
 Boolean value that determines whether a horizontal scroll indicator is shown in the `WebView`. The default value is `true`.
1006 1007
 
1007
-| Type | Required | Platform |
1008
-| ---- | -------- | -------- |
1008
+| Type | Required | Platform            |
1009
+| ---- | -------- | ------------------- |
1009 1010
 | bool | No       | iOS, Android, macOS |
1010 1011
 
1011 1012
 ---
@@ -1014,8 +1015,8 @@ Boolean value that determines whether a horizontal scroll indicator is shown in
1014 1015
 
1015 1016
 Boolean value that determines whether a vertical scroll indicator is shown in the `WebView`. The default value is `true`.
1016 1017
 
1017
-| Type | Required | Platform |
1018
-| ---- | -------- | -------- |
1018
+| Type | Required | Platform            |
1019
+| ---- | -------- | ------------------- |
1019 1020
 | bool | No       | iOS, Android, macOS |
1020 1021
 
1021 1022
 ---
@@ -1034,8 +1035,8 @@ Set whether Geolocation is enabled in the `WebView`. The default value is `false
1034 1035
 
1035 1036
 Boolean that sets whether JavaScript running in the context of a file scheme URL should be allowed to access content from other file scheme URLs. The default value is `false`.
1036 1037
 
1037
-| Type | Required | Platform |
1038
-| ---- | -------- | -------- |
1038
+| Type | Required | Platform            |
1039
+| ---- | -------- | ------------------- |
1039 1040
 | bool | No       | iOS, Android, macOS |
1040 1041
 
1041 1042
 ---
@@ -1114,8 +1115,8 @@ If true, this will be able horizontal swipe gestures. The default value is `fals
1114 1115
 
1115 1116
 Does not store any data within the lifetime of the WebView.
1116 1117
 
1117
-| Type    | Required | Platform |
1118
-| ------- | -------- | -------- |
1118
+| Type    | Required | Platform            |
1119
+| ------- | -------- | ------------------- |
1119 1120
 | boolean | No       | iOS, Android, macOS |
1120 1121
 
1121 1122
 ---
@@ -1144,8 +1145,8 @@ Sets whether the WebView should disable saving form data. The default value is `
1144 1145
 
1145 1146
 Sets whether WebView should use browser caching.
1146 1147
 
1147
-| Type    | Required | Default | Platform |
1148
-| ------- | -------- | ------- | -------- |
1148
+| Type    | Required | Default | Platform            |
1149
+| ------- | -------- | ------- | ------------------- |
1149 1150
 | boolean | No       | true    | iOS, Android, macOS |
1150 1151
 
1151 1152
 ---
@@ -1250,18 +1251,35 @@ the file.
1250 1251
 If not provided, the default is to let the webview try to render the file.
1251 1252
 
1252 1253
 Example:
1254
+
1253 1255
 ```jsx
1254 1256
 <WebView
1255 1257
   source={{ uri: 'https://reactnative.dev' }}
1256
-  onFileDownload={ ( { nativeEvent: { downloadUrl } } ) => {
1258
+  onFileDownload={({ nativeEvent: { downloadUrl } }) => {
1257 1259
     // You use downloadUrl which is a string to download files however you want.
1258 1260
   }}
1259
-  />
1261
+/>
1260 1262
 ```
1261 1263
 
1264
+| Type     | Required | Platform |
1265
+| -------- | -------- | -------- |
1266
+| function | No       | iOS      |
1267
+
1268
+---
1269
+
1270
+### `autoManageStatusBarEnabled`
1271
+
1272
+If set to `true`, the status bar will be automatically hidden/shown by WebView, specifically when full screen video is being watched. If `false`, WebView will not manage the status bar at all. The default value is `true`.
1273
+
1262 1274
 | Type    | Required | Platform |
1263 1275
 | ------- | -------- | -------- |
1264
-| function | No       | iOS      |
1276
+| boolean | No       | iOS      |
1277
+
1278
+Example:
1279
+
1280
+```javascript
1281
+<WebView autoManageStatusBarEnabled={false} />
1282
+```
1265 1283
 
1266 1284
 ## Methods
1267 1285
 
@@ -1326,6 +1344,7 @@ Request the webView to ask for focus. (People working on TV apps might want havi
1326 1344
 ```javascript
1327 1345
 postMessage('message');
1328 1346
 ```
1347
+
1329 1348
 Post a message to WebView, handled by [`onMessage`](Reference.md#onmessage).
1330 1349
 
1331 1350
 ### `clearFormData()`[⬆](#methods-index)<!-- Link generated with jump2header -->

+ 8
- 0
src/WebViewTypes.ts View File

@@ -311,6 +311,7 @@ export interface IOSNativeWebViewProps extends CommonNativeWebViewProps {
311 311
   allowsInlineMediaPlayback?: boolean;
312 312
   allowsLinkPreview?: boolean;
313 313
   automaticallyAdjustContentInsets?: boolean;
314
+  autoManageStatusBarEnabled?: boolean;
314 315
   bounces?: boolean;
315 316
   contentInset?: ContentInsetProp;
316 317
   contentInsetAdjustmentBehavior?: ContentInsetAdjustmentBehavior;
@@ -498,6 +499,13 @@ export interface IOSWebViewProps extends WebViewSharedProps {
498 499
    */
499 500
   sharedCookiesEnabled?: boolean;
500 501
 
502
+  /**
503
+   * Set true if StatusBar should be light when user watch video fullscreen.
504
+   * The default value is `true`.
505
+   * @platform ios
506
+   */
507
+  autoManageStatusBarEnabled?: boolean;
508
+
501 509
   /**
502 510
    * A Boolean value that determines whether scrolling is disabled in a particular direction.
503 511
    * The default value is `true`.