Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support keyboardDisplayRequiresUserAction to focus automaticlly in iOS #2312

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions dev_packages/generators/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ version: 1.0.0
publish_to: none

environment:
sdk: ^3.5.0
flutter: ">=3.24.0"
sdk: ">=3.4.0"
flutter: ">=3.22.3"

dependencies:
flutter:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,9 @@ class InAppWebViewController {
Future<InAppWebViewHitTestResult?> getHitTestResult() =>
platform.getHitTestResult();

///{@macro flutter_inappwebview_platform_interface.PlatformInAppWebViewController.requestFocus}
Future<void> requestFocus() => platform.requestFocus();

///{@macro flutter_inappwebview_platform_interface.PlatformInAppWebViewController.clearFocus}
Future<void> clearFocus() => platform.clearFocus();

Expand Down
4 changes: 2 additions & 2 deletions flutter_inappwebview/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ topics:
- browser

environment:
sdk: ^3.5.0
flutter: ">=3.24.0"
sdk: ^3.4.0
flutter: ">=3.22.3"

dependencies:
flutter:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,12 @@ public void onReceiveValue(String value) {
result.success(false);
}
break;
case requestFocus:
if (webView != null) {
webView.requestFocus();
}
result.success(true);
break;
case clearFocus:
if (webView != null) {
webView.clearFocus();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public enum WebViewChannelDelegateMethods {
saveWebArchive,
zoomIn,
zoomOut,
requestFocus,
clearFocus,
setContextMenu,
requestFocusNodeHref,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,11 @@ public boolean checkInputConnectionProxy(final View view) {
public void clearFocus() {
super.clearFocus();

InputMethodManager inputManager = (InputMethodManager) this.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
if (inputManager != null) {
inputManager.hideSoftInputFromWindow(this.getWindowToken(), 0);
}

if (useHybridComposition) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2241,6 +2241,12 @@ class AndroidInAppWebViewController extends PlatformInAppWebViewController
return InAppWebViewHitTestResult(type: type, extra: extra);
}

@override
Future<void> requestFocus() async {
Map<String, dynamic> args = <String, dynamic>{};
return await channel?.invokeMethod('requestFocus', args);
}

@override
Future<void> clearFocus() async {
Map<String, dynamic> args = <String, dynamic>{};
Expand Down
4 changes: 2 additions & 2 deletions flutter_inappwebview_android/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ topics:
- browser

environment:
sdk: ^3.5.0
flutter: ">=3.24.0"
sdk: ">=3.4.0"
flutter: ">=3.22.3"

dependencies:
flutter:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,75 @@ import Flutter
import Foundation
import WebKit

// Support `keyboardDisplayRequiresUserAction` to focus automaticlly
typealias OldClosureType = @convention(c) (Any, Selector, UnsafeRawPointer, Bool, Bool, Any?) -> Void
typealias NewClosureType = @convention(c) (Any, Selector, UnsafeRawPointer, Bool, Bool, Bool, Any?) -> Void
extension WKWebView{
var keyboardDisplayRequiresUserAction: Bool? {
get {
return self.keyboardDisplayRequiresUserAction
}
set {
self.setKeyboardRequiresUserInteraction(newValue ?? true)
}
}

func setKeyboardRequiresUserInteraction( _ value: Bool) {
guard let WKContentView: AnyClass = NSClassFromString("WKContentView") else {
print("keyboardDisplayRequiresUserAction extension: Cannot find the WKContentView class")
return
}
// For iOS 10, *
let sel_10: Selector = sel_getUid("_startAssistingNode:userIsInteracting:blurPreviousNode:userObject:")
// For iOS 11.3, *
let sel_11_3: Selector = sel_getUid("_startAssistingNode:userIsInteracting:blurPreviousNode:changingActivityState:userObject:")
// For iOS 12.2, *
let sel_12_2: Selector = sel_getUid("_elementDidFocus:userIsInteracting:blurPreviousNode:changingActivityState:userObject:")
// For iOS 13.0, *
let sel_13_0: Selector = sel_getUid("_elementDidFocus:userIsInteracting:blurPreviousNode:activityStateChanges:userObject:")

if let method = class_getInstanceMethod(WKContentView, sel_10) {
let originalImp: IMP = method_getImplementation(method)
let original: OldClosureType = unsafeBitCast(originalImp, to: OldClosureType.self)
let block : @convention(block) (Any, UnsafeRawPointer, Bool, Bool, Any?) -> Void = { (me, arg0, arg1, arg2, arg3) in
original(me, sel_10, arg0, !value, arg2, arg3)
}
let imp: IMP = imp_implementationWithBlock(block)
method_setImplementation(method, imp)
}

if let method = class_getInstanceMethod(WKContentView, sel_11_3) {
let originalImp: IMP = method_getImplementation(method)
let original: NewClosureType = unsafeBitCast(originalImp, to: NewClosureType.self)
let block : @convention(block) (Any, UnsafeRawPointer, Bool, Bool, Bool, Any?) -> Void = { (me, arg0, arg1, arg2, arg3, arg4) in
original(me, sel_11_3, arg0, !value, arg2, arg3, arg4)
}
let imp: IMP = imp_implementationWithBlock(block)
method_setImplementation(method, imp)
}

if let method = class_getInstanceMethod(WKContentView, sel_12_2) {
let originalImp: IMP = method_getImplementation(method)
let original: NewClosureType = unsafeBitCast(originalImp, to: NewClosureType.self)
let block : @convention(block) (Any, UnsafeRawPointer, Bool, Bool, Bool, Any?) -> Void = { (me, arg0, arg1, arg2, arg3, arg4) in
original(me, sel_12_2, arg0, !value, arg2, arg3, arg4)
}
let imp: IMP = imp_implementationWithBlock(block)
method_setImplementation(method, imp)
}

if let method = class_getInstanceMethod(WKContentView, sel_13_0) {
let originalImp: IMP = method_getImplementation(method)
let original: NewClosureType = unsafeBitCast(originalImp, to: NewClosureType.self)
let block : @convention(block) (Any, UnsafeRawPointer, Bool, Bool, Bool, Any?) -> Void = { (me, arg0, arg1, arg2, arg3, arg4) in
original(me, sel_13_0, arg0, !value, arg2, arg3, arg4)
}
let imp: IMP = imp_implementationWithBlock(block)
method_setImplementation(method, imp)
}
}
}

public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate,
WKNavigationDelegate, WKScriptMessageHandler, UIGestureRecognizerDelegate,
WKDownloadDelegate,
Expand Down Expand Up @@ -81,6 +150,7 @@ public class InAppWebView: WKWebView, UIScrollViewDelegate, WKUIDelegate,
}
self.contextMenu = contextMenu
self.initialUserScripts = userScripts
self.keyboardDisplayRequiresUserAction = false
uiDelegate = self
navigationDelegate = self
scrollView.delegate = self
Expand Down Expand Up @@ -3138,6 +3208,10 @@ if(window.\(JAVASCRIPT_BRIDGE_NAME)[\(_callHandlerID)] != null) {
}
}

public func requestFocus() {
self.scrollView.subviews.first?.becomeFirstResponder()
}

public func clearFocus() {
self.scrollView.subviews.first?.resignFirstResponder()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,10 @@ public class WebViewChannelDelegate: ChannelDelegate {
result(nil)
}
break
case .requestFocus:
webView?.requestFocus()
result(true)
break
case .clearFocus:
webView?.clearFocus()
result(true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public enum WebViewChannelDelegateMethods: String {
case hasOnlySecureContent = "hasOnlySecureContent"
case getSelectedText = "getSelectedText"
case getHitTestResult = "getHitTestResult"
case requestFocus = "requestFocus"
case clearFocus = "clearFocus"
case setContextMenu = "setContextMenu"
case requestFocusNodeHref = "requestFocusNodeHref"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2228,6 +2228,12 @@ class IOSInAppWebViewController extends PlatformInAppWebViewController
return InAppWebViewHitTestResult(type: type, extra: extra);
}

@override
Future<void> requestFocus() async {
Map<String, dynamic> args = <String, dynamic>{};
return await channel?.invokeMethod('requestFocus', args);
}

@override
Future<void> clearFocus() async {
Map<String, dynamic> args = <String, dynamic>{};
Expand Down
4 changes: 2 additions & 2 deletions flutter_inappwebview_ios/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ topics:
- browser

environment:
sdk: ^3.5.0
flutter: ">=3.24.0"
sdk: ">=3.4.0"
flutter: ">=3.22.3"

dependencies:
flutter:
Expand Down
4 changes: 2 additions & 2 deletions flutter_inappwebview_macos/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ topics:
- browser

environment:
sdk: ^3.5.0
flutter: ">=3.24.0"
sdk: ">=3.4.0"
flutter: ">=3.22.3"

dependencies:
flutter:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1048,6 +1048,13 @@ abstract class PlatformInAppWebViewController extends PlatformInterface
'getHitTestResult is not implemented on the current platform');
}

///{@template flutter_inappwebview_platform_interface.PlatformInAppWebViewController.requestFocus}
///{@endtemplate}
Future<void> requestFocus() {
throw UnimplementedError(
'requestFocus is not implemented on the current platform');
}

///{@template flutter_inappwebview_platform_interface.PlatformInAppWebViewController.clearFocus}
///Clears the current focus. On iOS and Android native WebView, it will clear also, for example, the current text selection.
///
Expand Down
4 changes: 2 additions & 2 deletions flutter_inappwebview_platform_interface/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ topics:
- browser

environment:
sdk: ^3.5.0
flutter: ">=3.24.0"
sdk: ">=3.4.0"
flutter: ">=3.22.3"

dependencies:
flutter:
Expand Down
4 changes: 2 additions & 2 deletions flutter_inappwebview_web/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ topics:
- browser

environment:
sdk: ^3.5.0
flutter: ">=3.24.0"
sdk: ">=3.4.0"
flutter: ">=3.22.3"

dependencies:
flutter:
Expand Down
4 changes: 2 additions & 2 deletions flutter_inappwebview_windows/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ topics:
- browser

environment:
sdk: ^3.5.0
flutter: ">=3.24.0"
sdk: ">=3.4.0"
flutter: ">=3.22.3"

dependencies:
flutter:
Expand Down