feat(WKWebView): Allow focus without user interaction (#540)
* [iOS] Allow focus without user interaction * Add documentation for keyboardDisplayRequiresUserAction * set keyboardDisplayRequiresUserAction default to true
This commit is contained in:
parent
c297e320d2
commit
455c30e000
|
@ -42,6 +42,7 @@ This document lays out the current public properties and methods for the React N
|
|||
- [`useWebKit`](Reference.md#usewebkit)
|
||||
- [`url`](Reference.md#url)
|
||||
- [`html`](Reference.md#html)
|
||||
- [`keyboardDisplayRequiresUserAction`](Reference.md#keyboardDisplayRequiresUserAction)
|
||||
- [`hideKeyboardAccessoryView`](Reference.md#hidekeyboardaccessoryview)
|
||||
- [`allowsBackForwardNavigationGestures`](Reference.md#allowsbackforwardnavigationgestures)
|
||||
- [`incognito`](Reference.md#incognito)
|
||||
|
@ -756,6 +757,16 @@ If true, use WKWebView instead of UIWebView.
|
|||
|
||||
---
|
||||
|
||||
### `keyboardDisplayRequiresUserAction`
|
||||
|
||||
If false, web content can programmatically display the keyboard when using the WKWebView. The default value is `true`.
|
||||
|
||||
| Type | Required | Platform |
|
||||
| ------- | -------- | -------- |
|
||||
| boolean | No | iOS |
|
||||
|
||||
---
|
||||
|
||||
### `hideKeyboardAccessoryView`
|
||||
|
||||
If true, this will hide the keyboard accessory view (< > and Done) when using the WKWebView.
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#endif
|
||||
@property (nonatomic, assign) UIEdgeInsets contentInset;
|
||||
@property (nonatomic, assign) BOOL automaticallyAdjustContentInsets;
|
||||
@property (nonatomic, assign) BOOL keyboardDisplayRequiresUserAction;
|
||||
@property (nonatomic, assign) BOOL hideKeyboardAccessoryView;
|
||||
@property (nonatomic, assign) BOOL allowsBackForwardNavigationGestures;
|
||||
@property (nonatomic, assign) BOOL incognito;
|
||||
|
|
|
@ -41,6 +41,7 @@ static NSURLCredential* clientAuthenticationCredential;
|
|||
{
|
||||
UIColor * _savedBackgroundColor;
|
||||
BOOL _savedHideKeyboardAccessoryView;
|
||||
BOOL _savedKeyboardDisplayRequiresUserAction;
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
|
@ -54,6 +55,7 @@ static NSURLCredential* clientAuthenticationCredential;
|
|||
_directionalLockEnabled = YES;
|
||||
_automaticallyAdjustContentInsets = YES;
|
||||
_contentInset = UIEdgeInsetsZero;
|
||||
_savedKeyboardDisplayRequiresUserAction = YES;
|
||||
}
|
||||
|
||||
// Workaround for a keyboard dismissal bug present in iOS 12
|
||||
|
@ -214,6 +216,7 @@ static NSURLCredential* clientAuthenticationCredential;
|
|||
|
||||
[self addSubview:_webView];
|
||||
[self setHideKeyboardAccessoryView: _savedHideKeyboardAccessoryView];
|
||||
[self setKeyboardDisplayRequiresUserAction: _savedKeyboardDisplayRequiresUserAction];
|
||||
[self visitSource];
|
||||
}
|
||||
}
|
||||
|
@ -364,6 +367,64 @@ static NSURLCredential* clientAuthenticationCredential;
|
|||
}
|
||||
}
|
||||
|
||||
-(void)setKeyboardDisplayRequiresUserAction:(BOOL)keyboardDisplayRequiresUserAction
|
||||
{
|
||||
if (_webView == nil) {
|
||||
_savedKeyboardDisplayRequiresUserAction = keyboardDisplayRequiresUserAction;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_savedKeyboardDisplayRequiresUserAction == true) {
|
||||
return;
|
||||
}
|
||||
|
||||
UIView* subview;
|
||||
|
||||
for (UIView* view in _webView.scrollView.subviews) {
|
||||
if([[view.class description] hasPrefix:@"WK"])
|
||||
subview = view;
|
||||
}
|
||||
|
||||
if(subview == nil) return;
|
||||
|
||||
Class class = subview.class;
|
||||
|
||||
NSOperatingSystemVersion iOS_11_3_0 = (NSOperatingSystemVersion){11, 3, 0};
|
||||
NSOperatingSystemVersion iOS_12_2_0 = (NSOperatingSystemVersion){12, 2, 0};
|
||||
|
||||
Method method;
|
||||
IMP override;
|
||||
|
||||
if ([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion: iOS_12_2_0]) {
|
||||
// iOS 12.2.0 - Future
|
||||
SEL selector = sel_getUid("_elementDidFocus:userIsInteracting:blurPreviousNode:changingActivityState:userObject:");
|
||||
method = class_getInstanceMethod(class, selector);
|
||||
IMP original = method_getImplementation(method);
|
||||
override = imp_implementationWithBlock(^void(id me, void* arg0, BOOL arg1, BOOL arg2, BOOL arg3, id arg4) {
|
||||
((void (*)(id, SEL, void*, BOOL, BOOL, BOOL, id))original)(me, selector, arg0, TRUE, arg2, arg3, arg4);
|
||||
});
|
||||
}
|
||||
else if ([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion: iOS_11_3_0]) {
|
||||
// iOS 11.3.0 - 12.2.0
|
||||
SEL selector = sel_getUid("_startAssistingNode:userIsInteracting:blurPreviousNode:changingActivityState:userObject:");
|
||||
method = class_getInstanceMethod(class, selector);
|
||||
IMP original = method_getImplementation(method);
|
||||
override = imp_implementationWithBlock(^void(id me, void* arg0, BOOL arg1, BOOL arg2, BOOL arg3, id arg4) {
|
||||
((void (*)(id, SEL, void*, BOOL, BOOL, BOOL, id))original)(me, selector, arg0, TRUE, arg2, arg3, arg4);
|
||||
});
|
||||
} else {
|
||||
// iOS 9.0 - 11.3.0
|
||||
SEL selector = sel_getUid("_startAssistingNode:userIsInteracting:blurPreviousNode:userObject:");
|
||||
method = class_getInstanceMethod(class, selector);
|
||||
IMP original = method_getImplementation(method);
|
||||
override = imp_implementationWithBlock(^void(id me, void* arg0, BOOL arg1, BOOL arg2, id arg3) {
|
||||
((void (*)(id, SEL, void*, BOOL, BOOL, id))original)(me, selector, arg0, TRUE, arg2, arg3);
|
||||
});
|
||||
}
|
||||
|
||||
method_setImplementation(method, override);
|
||||
}
|
||||
|
||||
-(void)setHideKeyboardAccessoryView:(BOOL)hideKeyboardAccessoryView
|
||||
{
|
||||
if (_webView == nil) {
|
||||
|
|
|
@ -101,6 +101,10 @@ RCT_CUSTOM_VIEW_PROPERTY(showsVerticalScrollIndicator, BOOL, RNCWKWebView) {
|
|||
view.showsVerticalScrollIndicator = json == nil ? true : [RCTConvert BOOL: json];
|
||||
}
|
||||
|
||||
RCT_CUSTOM_VIEW_PROPERTY(keyboardDisplayRequiresUserAction, BOOL, RNCWKWebView) {
|
||||
view.keyboardDisplayRequiresUserAction = json == nil ? true : [RCTConvert BOOL: json];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(injectJavaScript:(nonnull NSNumber *)reactTag script:(NSString *)script)
|
||||
{
|
||||
[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, RNCWKWebView *> *viewRegistry) {
|
||||
|
|
|
@ -403,6 +403,18 @@ export interface IOSWebViewProps extends WebViewSharedProps {
|
|||
*/
|
||||
directionalLockEnabled?: boolean;
|
||||
|
||||
/**
|
||||
* A Boolean value indicating whether web content can programmatically display the keyboard.
|
||||
*
|
||||
* When this property is set to true, the user must explicitly tap the elements in the
|
||||
* web view to display the keyboard (or other relevant input view) for that element.
|
||||
* When set to false, a focus event on an element causes the input view to be displayed
|
||||
* and associated with that element automatically.
|
||||
*
|
||||
* The default value is `true`.
|
||||
* @platform ios
|
||||
*/
|
||||
keyboardDisplayRequiresUserAction?: boolean;
|
||||
}
|
||||
|
||||
export interface AndroidWebViewProps extends WebViewSharedProps {
|
||||
|
|
Loading…
Reference in New Issue