From 22a60fd23a9ce396b11f498a6b338bf16510981b Mon Sep 17 00:00:00 2001 From: Kesha Antonov Date: Tue, 15 Sep 2020 07:42:09 +0700 Subject: [PATCH] feat(iOS): Add prop autoManageStatusBarEnabled (#914) Co-authored-by: Jamon Holmgren Co-authored-by: Jamon Holmgren Co-authored-by: Thibault Malbranche --- apple/RNCWebView.h | 1 + apple/RNCWebView.m | 12 +++- apple/RNCWebViewManager.m | 1 + docs/Reference.md | 123 ++++++++++++++++++++++---------------- src/WebViewTypes.ts | 8 +++ 5 files changed, 91 insertions(+), 54 deletions(-) diff --git a/apple/RNCWebView.h b/apple/RNCWebView.h index 2b6e23a..c2df02e 100644 --- a/apple/RNCWebView.h +++ b/apple/RNCWebView.h @@ -35,6 +35,7 @@ @property (nonatomic, assign) BOOL injectedJavaScriptBeforeContentLoadedForMainFrameOnly; @property (nonatomic, assign) BOOL scrollEnabled; @property (nonatomic, assign) BOOL sharedCookiesEnabled; +@property (nonatomic, assign) BOOL autoManageStatusBarEnabled; @property (nonatomic, assign) BOOL pagingEnabled; @property (nonatomic, assign) CGFloat decelerationRate; @property (nonatomic, assign) BOOL allowsInlineMediaPlayback; diff --git a/apple/RNCWebView.m b/apple/RNCWebView.m index 7107b6b..6e0ed7e 100644 --- a/apple/RNCWebView.m +++ b/apple/RNCWebView.m @@ -125,6 +125,7 @@ static NSDictionary* customCertificatesForHost; _showsVerticalScrollIndicator = YES; _directionalLockEnabled = YES; _automaticallyAdjustContentInsets = YES; + _autoManageStatusBarEnabled = YES; _contentInset = UIEdgeInsetsZero; _savedKeyboardDisplayRequiresUserAction = YES; #if !TARGET_OS_OSX @@ -335,9 +336,13 @@ static NSDictionary* customCertificatesForHost; -(void)showFullScreenVideoStatusBars { #pragma clang diagnostic ignored "-Wdeprecated-declarations" + if (!_autoManageStatusBarEnabled) { + return; + } + _isFullScreenVideoOpen = YES; RCTUnsafeExecuteOnMainQueueSync(^{ - [RCTSharedApplication() setStatusBarStyle:UIStatusBarStyleLightContent animated:YES]; + [RCTSharedApplication() setStatusBarStyle:self->_savedStatusBarStyle animated:YES]; }); #pragma clang diagnostic pop } @@ -345,6 +350,10 @@ static NSDictionary* customCertificatesForHost; -(void)hideFullScreenVideoStatusBars { #pragma clang diagnostic ignored "-Wdeprecated-declarations" + if (!_autoManageStatusBarEnabled) { + return; + } + _isFullScreenVideoOpen = NO; RCTUnsafeExecuteOnMainQueueSync(^{ [RCTSharedApplication() setStatusBarHidden:self->_savedStatusBarHidden animated:YES]; @@ -1375,4 +1384,3 @@ static NSDictionary* customCertificatesForHost; } @end - diff --git a/apple/RNCWebViewManager.m b/apple/RNCWebViewManager.m index 2d1125c..3fd1aff 100644 --- a/apple/RNCWebViewManager.m +++ b/apple/RNCWebViewManager.m @@ -66,6 +66,7 @@ RCT_EXPORT_VIEW_PROPERTY(dataDetectorTypes, WKDataDetectorTypes) #endif RCT_EXPORT_VIEW_PROPERTY(contentInset, UIEdgeInsets) RCT_EXPORT_VIEW_PROPERTY(automaticallyAdjustContentInsets, BOOL) +RCT_EXPORT_VIEW_PROPERTY(autoManageStatusBarEnabled, BOOL) RCT_EXPORT_VIEW_PROPERTY(hideKeyboardAccessoryView, BOOL) RCT_EXPORT_VIEW_PROPERTY(allowsBackForwardNavigationGestures, BOOL) RCT_EXPORT_VIEW_PROPERTY(incognito, BOOL) diff --git a/docs/Reference.md b/docs/Reference.md index de02777..444ca95 100644 --- a/docs/Reference.md +++ b/docs/Reference.md @@ -71,6 +71,7 @@ This document lays out the current public properties and methods for the React N - [`pullToRefreshEnabled`](Reference.md#pullToRefreshEnabled) - [`ignoreSilentHardwareSwitch`](Reference.md#ignoreSilentHardwareSwitch) - [`onFileDownload`](Reference.md#onFileDownload) +- [`autoManageStatusBarEnabled`](Reference.md#autoManageStatusBarEnabled) ## Methods Index @@ -136,9 +137,9 @@ Make sure the string evaluates to a valid type (`true` works) and doesn't otherw On iOS, see [`WKUserScriptInjectionTimeAtDocumentEnd`](https://developer.apple.com/documentation/webkit/wkuserscriptinjectiontime/wkuserscriptinjectiontimeatdocumentend?language=objc) -| Type | Required | Platform | -| ------ | -------- | -------- | -| string | No | iOS, Android, macOS +| Type | Required | Platform | +| ------ | -------- | ------------------- | +| string | No | iOS, Android, macOS | To learn more, read the [Communicating between JS and Native](Guide.md#communicating-between-js-and-native) guide. @@ -168,15 +169,15 @@ Make sure the string evaluates to a valid type (`true` works) and doesn't otherw On iOS, see [`WKUserScriptInjectionTimeAtDocumentStart`](https://developer.apple.com/documentation/webkit/wkuserscriptinjectiontime/wkuserscriptinjectiontimeatdocumentstart?language=objc) -| Type | Required | Platform | -| ------ | -------- | -------- | +| Type | Required | Platform | +| ------ | -------- | ---------- | | string | No | iOS, macOS | To learn more, read the [Communicating between JS and Native](Guide.md#communicating-between-js-and-native) guide. Example: -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. +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. ```jsx const INJECTED_JAVASCRIPT = `(function() { @@ -198,8 +199,8 @@ If `true` (default; mandatory for Android), loads the `injectedJavaScript` only If `false`, (only supported on iOS and macOS), loads it into all frames (e.g. iframes). -| Type | Required | Platform | -| ------ | -------- | -------- | +| Type | Required | Platform | +| ---- | -------- | ------------------------------------------------- | | bool | No | iOS and macOS (only `true` supported for Android) | --- @@ -210,8 +211,8 @@ If `true` (default; mandatory for Android), loads the `injectedJavaScriptBeforeC If `false`, (only supported on iOS and macOS), loads it into all frames (e.g. iframes). -| Type | Required | Platform | -| ------ | -------- | -------- | +| Type | Required | Platform | +| ---- | -------- | ------------------------------------------------- | | bool | No | iOS and macOS (only `true` supported for Android) | --- @@ -222,8 +223,8 @@ Boolean that determines whether HTML5 audio and video requires the user to tap t NOTE: the default `true` value might cause some videos to hang loading on iOS. Setting it to `false` could fix this issue. -| Type | Required | Platform | -| ---- | -------- | -------- | +| Type | Required | Platform | +| ---- | -------- | ------------------- | | bool | No | iOS, Android, macOS | --- @@ -238,8 +239,8 @@ The `nativeConfig` prop expects an object with the following keys: - `props` (object) - `viewManager` (object) -| Type | Required | Platform | -| ------ | -------- | -------- | +| Type | Required | Platform | +| ------ | -------- | ------------------- | | object | No | iOS, Android, macOS | --- @@ -257,7 +258,7 @@ Example: ```jsx { + onError={(syntheticEvent) => { const { nativeEvent } = syntheticEvent; console.warn('WebView error: ', nativeEvent); }} @@ -297,7 +298,7 @@ Example: ```jsx { + onLoad={(syntheticEvent) => { const { nativeEvent } = syntheticEvent; this.url = nativeEvent.url; }} @@ -330,7 +331,7 @@ Example: ```jsx { + onLoadEnd={(syntheticEvent) => { // update component to be aware of loading status const { nativeEvent } = syntheticEvent; this.isLoading = nativeEvent.loading; @@ -364,7 +365,7 @@ Example: ```jsx { + onLoadStart={(syntheticEvent) => { // update component to be aware of loading status const { nativeEvent } = syntheticEvent; this.isLoading = nativeEvent.loading; @@ -389,8 +390,8 @@ url Function that is invoked when the `WebView` is loading. -| Type | Required | Platform | -| -------- | -------- | --------- | +| Type | Required | Platform | +| -------- | -------- | ------------------- | | function | No | iOS, Android, macOS | Example: @@ -434,7 +435,7 @@ Example: ```jsx { + onHttpError={(syntheticEvent) => { const { nativeEvent } = syntheticEvent; console.warn( 'WebView received error status code: ', @@ -522,7 +523,7 @@ Example: ```jsx { + onNavigationStateChange={(navState) => { // Keep track of going back navigation within component this.canGoBack = navState.canGoBack; }} @@ -556,7 +557,7 @@ Example: ```jsx { + onContentProcessDidTerminate={(syntheticEvent) => { const { nativeEvent } = syntheticEvent; console.warn('Content process terminated, reloading', nativeEvent); this.refs.webview.reload(); @@ -581,8 +582,8 @@ url 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://*". -| Type | Required | Platform | -| ---------------- | -------- | -------- | +| Type | Required | Platform | +| ---------------- | -------- | ------------------- | | array of strings | No | iOS, Android, macOS | Example: @@ -601,8 +602,8 @@ Example: Function that returns a view to show if there's an error. -| Type | Required | Platform | -| -------- | -------- | -------- | +| Type | Required | Platform | +| -------- | -------- | ------------------- | | function | No | iOS, Android, macOS | Example: @@ -610,7 +611,7 @@ Example: ```jsx } + renderError={(errorName) => } /> ``` @@ -622,8 +623,8 @@ The function passed to `renderError` will be called with the name of the error Function that returns a loading indicator. The startInLoadingState prop must be set to true in order to use this prop. -| Type | Required | Platform | -| -------- | -------- | -------- | +| Type | Required | Platform | +| -------- | -------- | ------------------- | | function | No | iOS, Android, macOS | Example: @@ -654,8 +655,8 @@ Function that allows custom handling of any web view requests. Return `true` fro On Android, is not called on the first load. -| Type | Required | Platform | -| -------- | -------- | -------- | +| Type | Required | Platform | +| -------- | -------- | ------------------- | | function | No | iOS, Android, macOS | Example: @@ -663,7 +664,7 @@ Example: ```jsx { + onShouldStartLoadWithRequest={(request) => { // Only allow navigating within this website return request.url.startsWith('https://reactnative.dev'); }} @@ -691,8 +692,8 @@ isTopFrame 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. -| Type | Required | Platform | -| ---- | -------- | -------- | +| Type | Required | Platform | +| ---- | -------- | ------------------- | | bool | No | iOS, Android, macOS | --- @@ -836,8 +837,8 @@ Boolean value to enable third party cookies in the `WebView`. Used on Android Lo Sets the user-agent for the `WebView`. -| Type | Required | Platform | -| ------ | -------- | -------- | +| Type | Required | Platform | +| ------ | -------- | ------------------- | | string | No | iOS, Android, macOS | --- @@ -846,8 +847,8 @@ Sets the user-agent for the `WebView`. Append to the existing user-agent. Setting `userAgent` will override this. -| Type | Required | Platform | -| ------ | -------- | -------- | +| Type | Required | Platform | +| ------ | -------- | ------------------- | | string | No | iOS, Android, macOS | ```jsx @@ -1004,8 +1005,8 @@ The default value is `true`. Boolean value that determines whether a horizontal scroll indicator is shown in the `WebView`. The default value is `true`. -| Type | Required | Platform | -| ---- | -------- | -------- | +| Type | Required | Platform | +| ---- | -------- | ------------------- | | bool | No | iOS, Android, macOS | --- @@ -1014,8 +1015,8 @@ Boolean value that determines whether a horizontal scroll indicator is shown in Boolean value that determines whether a vertical scroll indicator is shown in the `WebView`. The default value is `true`. -| Type | Required | Platform | -| ---- | -------- | -------- | +| Type | Required | Platform | +| ---- | -------- | ------------------- | | bool | No | iOS, Android, macOS | --- @@ -1034,8 +1035,8 @@ Set whether Geolocation is enabled in the `WebView`. The default value is `false 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`. -| Type | Required | Platform | -| ---- | -------- | -------- | +| Type | Required | Platform | +| ---- | -------- | ------------------- | | bool | No | iOS, Android, macOS | --- @@ -1114,8 +1115,8 @@ If true, this will be able horizontal swipe gestures. The default value is `fals Does not store any data within the lifetime of the WebView. -| Type | Required | Platform | -| ------- | -------- | -------- | +| Type | Required | Platform | +| ------- | -------- | ------------------- | | boolean | No | iOS, Android, macOS | --- @@ -1144,8 +1145,8 @@ Sets whether the WebView should disable saving form data. The default value is ` Sets whether WebView should use browser caching. -| Type | Required | Default | Platform | -| ------- | -------- | ------- | -------- | +| Type | Required | Default | Platform | +| ------- | -------- | ------- | ------------------- | | boolean | No | true | iOS, Android, macOS | --- @@ -1250,18 +1251,35 @@ the file. If not provided, the default is to let the webview try to render the file. Example: + ```jsx { + onFileDownload={({ nativeEvent: { downloadUrl } }) => { // You use downloadUrl which is a string to download files however you want. }} - /> +/> ``` +| Type | Required | Platform | +| -------- | -------- | -------- | +| function | No | iOS | + +--- + +### `autoManageStatusBarEnabled` + +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`. + | Type | Required | Platform | | ------- | -------- | -------- | -| function | No | iOS | +| boolean | No | iOS | + +Example: + +```javascript + +``` ## Methods @@ -1326,6 +1344,7 @@ Request the webView to ask for focus. (People working on TV apps might want havi ```javascript postMessage('message'); ``` + Post a message to WebView, handled by [`onMessage`](Reference.md#onmessage). ### `clearFormData()`[⬆](#methods-index) diff --git a/src/WebViewTypes.ts b/src/WebViewTypes.ts index bac8950..516cfd8 100644 --- a/src/WebViewTypes.ts +++ b/src/WebViewTypes.ts @@ -311,6 +311,7 @@ export interface IOSNativeWebViewProps extends CommonNativeWebViewProps { allowsInlineMediaPlayback?: boolean; allowsLinkPreview?: boolean; automaticallyAdjustContentInsets?: boolean; + autoManageStatusBarEnabled?: boolean; bounces?: boolean; contentInset?: ContentInsetProp; contentInsetAdjustmentBehavior?: ContentInsetAdjustmentBehavior; @@ -498,6 +499,13 @@ export interface IOSWebViewProps extends WebViewSharedProps { */ sharedCookiesEnabled?: boolean; + /** + * Set true if StatusBar should be light when user watch video fullscreen. + * The default value is `true`. + * @platform ios + */ + autoManageStatusBarEnabled?: boolean; + /** * A Boolean value that determines whether scrolling is disabled in a particular direction. * The default value is `true`.