From 493b65de21b79194b697bb839690339cd826404a Mon Sep 17 00:00:00 2001 From: aarondail Date: Fri, 9 Aug 2019 01:55:35 -0700 Subject: [PATCH] feat(iOS): added `contentInsetAdjustmentBehavior` prop * Adding a `contentInsetAdjustmentBehavior` prop to the WebView for iOS. This controls the way iOS will automatically adjust the insets when the webview is behind things like the iPhone X notch. * Removing the code to explicitly pass contentInsetAdjustmentBehavior to the WebView since it is already passed in otherProps. --- docs/Reference.md | 18 ++++++++++++++++++ ios/RNCWKWebView.m | 26 +++++++++++++++++++++++++- ios/RNCWKWebViewManager.m | 17 +++++++++++++++++ src/WebViewTypes.ts | 8 ++++++++ 4 files changed, 68 insertions(+), 1 deletion(-) diff --git a/docs/Reference.md b/docs/Reference.md index 66ae88c..cf928d8 100644 --- a/docs/Reference.md +++ b/docs/Reference.md @@ -36,6 +36,7 @@ This document lays out the current public properties and methods for the React N - [`bounces`](Reference.md#bounces) - [`overScrollMode`](Reference.md#overscrollmode) - [`contentInset`](Reference.md#contentinset) +- [`contentInsetAdjustmentBehavior`](Reference.md#contentInsetAdjustmentBehavior) - [`dataDetectorTypes`](Reference.md#datadetectortypes) - [`scrollEnabled`](Reference.md#scrollenabled) - [`directionalLockEnabled`](Reference.md#directionalLockEnabled) @@ -689,6 +690,23 @@ The amount by which the web view content is inset from the edges of the scroll v --- +### `contentInsetAdjustmentBehavior` + +This property specifies how the safe area insets are used to modify the content area of the scroll view. The default value of this property is "never". Available on iOS 11 and later. Defaults to `never`. + +Possible values: + +- `automatic` +- `scrollableAxes` +- `never` +- `always` + +| Type | Required | Platform | +| ------ | -------- | -------- | +| string | No | iOS | + +--- + ### `dataDetectorTypes` Determines the types of data converted to clickable URLs in the web view's content. By default only phone numbers are detected. diff --git a/ios/RNCWKWebView.m b/ios/RNCWKWebView.m index abbb74d..107ab72 100644 --- a/ios/RNCWKWebView.m +++ b/ios/RNCWKWebView.m @@ -49,6 +49,10 @@ static NSURLCredential* clientAuthenticationCredential; BOOL _isFullScreenVideoOpen; UIStatusBarStyle _savedStatusBarStyle; BOOL _savedStatusBarHidden; + +#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */ + UIScrollViewContentInsetAdjustmentBehavior _savedContentInsetAdjustmentBehavior; +#endif } - (instancetype)initWithFrame:(CGRect)frame @@ -65,6 +69,10 @@ static NSURLCredential* clientAuthenticationCredential; _savedKeyboardDisplayRequiresUserAction = YES; _savedStatusBarStyle = RCTSharedApplication().statusBarStyle; _savedStatusBarHidden = RCTSharedApplication().statusBarHidden; + +#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */ + _savedContentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; +#endif } if (@available(iOS 12.0, *)) { @@ -227,7 +235,7 @@ static NSURLCredential* clientAuthenticationCredential; } #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */ if ([_webView.scrollView respondsToSelector:@selector(setContentInsetAdjustmentBehavior:)]) { - _webView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; + _webView.scrollView.contentInsetAdjustmentBehavior = _savedContentInsetAdjustmentBehavior; } #endif @@ -328,6 +336,22 @@ static NSURLCredential* clientAuthenticationCredential; _webView.backgroundColor = backgroundColor; } +#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */ +- (void)setContentInsetAdjustmentBehavior:(UIScrollViewContentInsetAdjustmentBehavior)behavior +{ + _savedContentInsetAdjustmentBehavior = behavior; + if (_webView == nil) { + return; + } + + if ([_webView.scrollView respondsToSelector:@selector(setContentInsetAdjustmentBehavior:)]) { + CGPoint contentOffset = _webView.scrollView.contentOffset; + _webView.scrollView.contentInsetAdjustmentBehavior = behavior; + _webView.scrollView.contentOffset = contentOffset; + } +} +#endif + /** * This method is called whenever JavaScript running within the web view calls: * - window.webkit.messageHandlers[MessageHandlerName].postMessage diff --git a/ios/RNCWKWebViewManager.m b/ios/RNCWKWebViewManager.m index d4408f2..0c3d150 100644 --- a/ios/RNCWKWebViewManager.m +++ b/ios/RNCWKWebViewManager.m @@ -14,6 +14,19 @@ @interface RNCWKWebViewManager () @end +@implementation RCTConvert (UIScrollView) + +#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */ +RCT_ENUM_CONVERTER(UIScrollViewContentInsetAdjustmentBehavior, (@{ + @"automatic": @(UIScrollViewContentInsetAdjustmentAutomatic), + @"scrollableAxes": @(UIScrollViewContentInsetAdjustmentScrollableAxes), + @"never": @(UIScrollViewContentInsetAdjustmentNever), + @"always": @(UIScrollViewContentInsetAdjustmentAlways), + }), UIScrollViewContentInsetAdjustmentNever, integerValue) +#endif + +@end + @implementation RNCWKWebViewManager { NSConditionLock *_shouldStartLoadLock; @@ -52,6 +65,10 @@ RCT_EXPORT_VIEW_PROPERTY(applicationNameForUserAgent, NSString) RCT_EXPORT_VIEW_PROPERTY(cacheEnabled, BOOL) RCT_EXPORT_VIEW_PROPERTY(allowsLinkPreview, BOOL) +#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */ +RCT_EXPORT_VIEW_PROPERTY(contentInsetAdjustmentBehavior, UIScrollViewContentInsetAdjustmentBehavior) +#endif + /** * Expose methods to enable messaging the webview. */ diff --git a/src/WebViewTypes.ts b/src/WebViewTypes.ts index 4bbda15..4ec1f86 100644 --- a/src/WebViewTypes.ts +++ b/src/WebViewTypes.ts @@ -260,6 +260,7 @@ export interface IOSNativeWebViewProps extends CommonNativeWebViewProps { automaticallyAdjustContentInsets?: boolean; bounces?: boolean; contentInset?: ContentInsetProp; + contentInsetAdjustmentBehavior?: 'automatic'| 'scrollableAxes' | 'never' | 'always'; dataDetectorTypes?: DataDetectorTypes | ReadonlyArray; decelerationRate?: number; directionalLockEnabled?: boolean; @@ -324,6 +325,13 @@ export interface IOSWebViewProps extends WebViewSharedProps { */ automaticallyAdjustContentInsets?: boolean; + /** + * This property specifies how the safe area insets are used to modify the + * content area of the scroll view. The default value of this property is + * "never". Available on iOS 11 and later. + */ + contentInsetAdjustmentBehavior?: 'automatic'| 'scrollableAxes' | 'never' | 'always' + /** * The amount by which the web view content is inset from the edges of * the scroll view. Defaults to {top: 0, left: 0, bottom: 0, right: 0}.