Implement 'automaticallyAdjustContentInsets' and 'contentInset' props

Summary:
@public

This diff introduces two new props:
1. **automaticallyAdjustContentInsets**: Controls whether to adjust the content inset for web views that are placed behind a navigation bar, tab bar, or toolbar. The default value is true.
1. **contentInset**: 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}.

**Note:** There're some inconsistencies between how `UIWebView` and `WKWebView` render web pages with respect to the `contentInset` property. These two videos illustrate the problem:

**UIWebView**
[[ P58674349 | Playground.js ]]
https://pxl.cl/9R9V

**WKWebView**
[[ P58674348 | Playground.js ]]
https://pxl.cl/9R9W

Here's a stack overflow answer describing the problem: https://stackoverflow.com/a/35472603.

Reviewed By: shergin

Differential Revision: D6432181

fbshipit-source-id: aee6dac65d28435381ebec90519474b4707c7bab
This commit is contained in:
Ramanpreet Nara 2018-08-16 13:34:26 -07:00 committed by Facebook Github Bot
parent 215fa14efc
commit bacfd92976
3 changed files with 29 additions and 1 deletions

View File

@ -32,6 +32,8 @@ shouldStartLoadForRequest:(NSMutableDictionary<NSString *, id> *)request
@property (nonatomic, assign) BOOL bounces;
@property (nonatomic, assign) BOOL mediaPlaybackRequiresUserAction;
@property (nonatomic, assign) WKDataDetectorTypes dataDetectorTypes;
@property (nonatomic, assign) UIEdgeInsets contentInset;
@property (nonatomic, assign) BOOL automaticallyAdjustContentInsets;
- (void)postMessage:(NSString *)message;
- (void)injectJavaScript:(NSString *)script;

View File

@ -4,7 +4,7 @@
static NSString *const MessageHanderName = @"ReactNative";
@interface RCTWKWebView () <WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler, UIScrollViewDelegate>
@interface RCTWKWebView () <WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler, UIScrollViewDelegate, RCTAutoInsetsProtocol>
@property (nonatomic, copy) RCTDirectEventBlock onLoadingStart;
@property (nonatomic, copy) RCTDirectEventBlock onLoadingFinish;
@property (nonatomic, copy) RCTDirectEventBlock onLoadingError;
@ -29,6 +29,8 @@ static NSString *const MessageHanderName = @"ReactNative";
super.backgroundColor = [UIColor clearColor];
_bounces = YES;
_scrollEnabled = YES;
_automaticallyAdjustContentInsets = YES;
_contentInset = UIEdgeInsetsZero;
}
return self;
}
@ -51,6 +53,13 @@ static NSString *const MessageHanderName = @"ReactNative";
_webView.navigationDelegate = self;
_webView.scrollView.scrollEnabled = _scrollEnabled;
_webView.scrollView.bounces = _bounces;
#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;
}
#endif
[self addSubview:_webView];
[self visitSource];
@ -95,6 +104,21 @@ static NSString *const MessageHanderName = @"ReactNative";
}
}
- (void)setContentInset:(UIEdgeInsets)contentInset
{
_contentInset = contentInset;
[RCTView autoAdjustInsetsForView:self
withScrollView:_webView.scrollView
updateOffset:NO];
}
- (void)refreshContentInset
{
[RCTView autoAdjustInsetsForView:self
withScrollView:_webView.scrollView
updateOffset:YES];
}
- (void)visitSource
{
// Check for a static html source first

View File

@ -30,6 +30,8 @@ RCT_EXPORT_VIEW_PROPERTY(injectedJavaScript, NSString)
RCT_EXPORT_VIEW_PROPERTY(allowsInlineMediaPlayback, BOOL)
RCT_EXPORT_VIEW_PROPERTY(mediaPlaybackRequiresUserAction, BOOL)
RCT_EXPORT_VIEW_PROPERTY(dataDetectorTypes, WKDataDetectorTypes)
RCT_EXPORT_VIEW_PROPERTY(contentInset, UIEdgeInsets)
RCT_EXPORT_VIEW_PROPERTY(automaticallyAdjustContentInsets, BOOL)
/**
* Expose methods to enable messaging the webview.