Browse Source

feat(New WebView Prop): [iOS] add hideKeyboardAccessoryView option (#67)

* add hideKeyboardAccessoryView option

* add hideKeyboardAccessoryView prop to reference
marcelkalveram 6 years ago
parent
commit
34512f3c38
6 changed files with 69 additions and 1 deletions
  1. 11
    0
      docs/Reference.md
  2. 1
    0
      ios/RNCWKWebView.h
  3. 50
    1
      ios/RNCWKWebView.m
  4. 1
    0
      ios/RNCWKWebViewManager.m
  5. 1
    0
      js/WebView.ios.js
  6. 5
    0
      js/WebViewTypes.js

+ 11
- 0
docs/Reference.md View File

@@ -43,6 +43,7 @@ This document lays out the current public properties and methods for the React N
43 43
 - [`useWebKit`](Reference.md#usewebkit)
44 44
 - [`url`](Reference.md#url)
45 45
 - [`html`](Reference.md#html)
46
+- [`hideKeyboardAccessoryView`](Reference.md#hidekeyboardaccessoryview)
46 47
 
47 48
 ## Methods Index
48 49
 
@@ -483,6 +484,16 @@ If true, use WKWebView instead of UIWebView.
483 484
 | ------ | -------- |
484 485
 | string | No       |
485 486
 
487
+---
488
+
489
+### `hideKeyboardAccessoryView`
490
+
491
+If true, this will hide the keyboard accessory view (< > and Done) when using the WKWebView.
492
+
493
+| Type    | Required | Platform |
494
+| ------- | -------- | -------- |
495
+| boolean | No       | iOS      |
496
+
486 497
 ## Methods
487 498
 
488 499
 ### `extraNativeComponentConfig()`

+ 1
- 0
ios/RNCWKWebView.h View File

@@ -35,6 +35,7 @@ shouldStartLoadForRequest:(NSMutableDictionary<NSString *, id> *)request
35 35
 #endif
36 36
 @property (nonatomic, assign) UIEdgeInsets contentInset;
37 37
 @property (nonatomic, assign) BOOL automaticallyAdjustContentInsets;
38
+@property (nonatomic, assign) BOOL hideKeyboardAccessoryView;
38 39
 
39 40
 - (void)postMessage:(NSString *)message;
40 41
 - (void)injectJavaScript:(NSString *)script;

+ 50
- 1
ios/RNCWKWebView.m View File

@@ -9,8 +9,20 @@
9 9
 #import <React/RCTConvert.h>
10 10
 #import <React/RCTAutoInsetsProtocol.h>
11 11
 
12
+#import "objc/runtime.h"
13
+
12 14
 static NSString *const MessageHanderName = @"ReactNative";
13 15
 
16
+// runtime trick to remove WKWebView keyboard default toolbar
17
+// see: http://stackoverflow.com/questions/19033292/ios-7-uiwebview-keyboard-issue/19042279#19042279
18
+@interface _SwizzleHelperWK : NSObject @end
19
+@implementation _SwizzleHelperWK
20
+-(id)inputAccessoryView
21
+{
22
+  return nil;
23
+}
24
+@end
25
+
14 26
 @interface RNCWKWebView () <WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler, UIScrollViewDelegate, RCTAutoInsetsProtocol>
15 27
 @property (nonatomic, copy) RCTDirectEventBlock onLoadingStart;
16 28
 @property (nonatomic, copy) RCTDirectEventBlock onLoadingFinish;
@@ -24,6 +36,7 @@ static NSString *const MessageHanderName = @"ReactNative";
24 36
 @implementation RNCWKWebView
25 37
 {
26 38
   UIColor * _savedBackgroundColor;
39
+  BOOL _savedHideKeyboardAccessoryView;
27 40
 }
28 41
 
29 42
 - (void)dealloc
@@ -97,7 +110,7 @@ static NSString *const MessageHanderName = @"ReactNative";
97 110
 #endif
98 111
 
99 112
     [self addSubview:_webView];
100
-
113
+    [self setHideKeyboardAccessoryView: _savedHideKeyboardAccessoryView];
101 114
     [self visitSource];
102 115
   } else {
103 116
     [_webView.configuration.userContentController removeScriptMessageHandlerForName:MessageHanderName];
@@ -198,6 +211,42 @@ static NSString *const MessageHanderName = @"ReactNative";
198 211
   [_webView loadRequest:request];
199 212
 }
200 213
 
214
+-(void)setHideKeyboardAccessoryView:(BOOL)hideKeyboardAccessoryView
215
+{
216
+    
217
+    if (_webView == nil) {
218
+        _savedHideKeyboardAccessoryView = hideKeyboardAccessoryView;
219
+        return;
220
+    }
221
+
222
+    if (_savedHideKeyboardAccessoryView == false) {
223
+        return;
224
+    }
225
+    
226
+    UIView* subview;
227
+    for (UIView* view in _webView.scrollView.subviews) {
228
+        if([[view.class description] hasPrefix:@"WK"])
229
+            subview = view;
230
+    }
231
+    
232
+    if(subview == nil) return;
233
+    
234
+    NSString* name = [NSString stringWithFormat:@"%@_SwizzleHelperWK", subview.class.superclass];
235
+    Class newClass = NSClassFromString(name);
236
+    
237
+    if(newClass == nil)
238
+    {
239
+        newClass = objc_allocateClassPair(subview.class, [name cStringUsingEncoding:NSASCIIStringEncoding], 0);
240
+        if(!newClass) return;
241
+        
242
+        Method method = class_getInstanceMethod([_SwizzleHelperWK class], @selector(inputAccessoryView));
243
+        class_addMethod(newClass, @selector(inputAccessoryView), method_getImplementation(method), method_getTypeEncoding(method));
244
+        
245
+        objc_registerClassPair(newClass);
246
+    }
247
+    
248
+    object_setClass(subview, newClass);
249
+}
201 250
 
202 251
 - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
203 252
 {

+ 1
- 0
ios/RNCWKWebViewManager.m View File

@@ -43,6 +43,7 @@ RCT_EXPORT_VIEW_PROPERTY(dataDetectorTypes, WKDataDetectorTypes)
43 43
 #endif
44 44
 RCT_EXPORT_VIEW_PROPERTY(contentInset, UIEdgeInsets)
45 45
 RCT_EXPORT_VIEW_PROPERTY(automaticallyAdjustContentInsets, BOOL)
46
+RCT_EXPORT_VIEW_PROPERTY(hideKeyboardAccessoryView, BOOL)
46 47
 
47 48
 /**
48 49
  * Expose methods to enable messaging the webview.

+ 1
- 0
js/WebView.ios.js View File

@@ -261,6 +261,7 @@ class WebView extends React.Component<WebViewSharedProps, State> {
261 261
         automaticallyAdjustContentInsets={
262 262
           this.props.automaticallyAdjustContentInsets
263 263
         }
264
+        hideKeyboardAccessoryView={this.props.hideKeyboardAccessoryView}
264 265
         onLoadingStart={this._onLoadingStart}
265 266
         onLoadingFinish={this._onLoadingFinish}
266 267
         onLoadingError={this._onLoadingError}

+ 5
- 0
js/WebViewTypes.js View File

@@ -219,6 +219,11 @@ export type IOSWebViewProps = $ReadOnly<{|
219 219
    * @platform ios
220 220
    */
221 221
   allowsInlineMediaPlayback?: ?boolean,
222
+  /**
223
+   * Hide the accessory view when the keyboard is open. Default is false to be
224
+   * backward compatible.
225
+   */
226
+  hideKeyboardAccessoryView?: ?boolean,
222 227
 |}>;
223 228
 
224 229
 export type AndroidWebViewProps = $ReadOnly<{|