情景描述
我們知道弯洗,UIWebView是有一個 keyboardDisplayRequiresUserAction屬性的,默認為YES岳掐。如果設置為YES伪嫁,用戶必須明確的點擊頁面上的元素或者相關聯(lián)的輸入頁面來顯示鍵盤;如果設置為NO西壮,一個元素的焦點事件導致輸入視圖的顯示和自動關聯(lián)這個元素遗增。
那么,如果我們加載一個Web頁面時款青,想一開始喚起鍵盤做修,除了web端需要設置input 的focus狀態(tài)外,我們還需要將keyboardDisplayRequiresUserAction設置為false
問題
然而抡草,WKWebView是沒有這個屬性的饰及,但又想做到以上效果,怎么辦呢康震?只能通過runtime處理了旋炒,以下是收集Stack Overflow的方法
OC版本
#import <objc/runtime.h>
@implementation WebViewInjection
+ (void)allowDisplayingKeyboardWithoutUserAction {
Class class = NSClassFromString(@"WKContentView");
NSOperatingSystemVersion iOS_11_3_0 = (NSOperatingSystemVersion){11, 3, 0};
if ([[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion: iOS_11_3_0]) {
SEL selector = sel_getUid("_startAssistingNode:userIsInteracting:blurPreviousNode:changingActivityState:userObject:");
Method method = class_getInstanceMethod(class, selector);
IMP original = method_getImplementation(method);
IMP 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);
});
method_setImplementation(method, override);
} else {
SEL selector = sel_getUid("_startAssistingNode:userIsInteracting:blurPreviousNode:userObject:");
Method method = class_getInstanceMethod(class, selector);
IMP original = method_getImplementation(method);
IMP 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);
}
}
@end
Swift版本
typealias OlderClosureType = @convention(c) (Any, Selector, UnsafeRawPointer, Bool, Bool, Any?) -> Void
typealias NewerClosureType = @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 WKContentViewClass: AnyClass = NSClassFromString("WKContentView") else {
print("Cannot find the WKContentView class")
return
}
let olderSelector: Selector = sel_getUid("_startAssistingNode:userIsInteracting:blurPreviousNode:userObject:")
let newerSelector: Selector = sel_getUid("_startAssistingNode:userIsInteracting:blurPreviousNode:changingActivityState:userObject:")
if let method = class_getInstanceMethod(WKContentViewClass, olderSelector) {
let originalImp: IMP = method_getImplementation(method)
let original: OlderClosureType = unsafeBitCast(originalImp, to: OlderClosureType.self)
let block : @convention(block) (Any, UnsafeRawPointer, Bool, Bool, Any?) -> Void = { (me, arg0, arg1, arg2, arg3) in
original(me, olderSelector, arg0, !value, arg2, arg3)
}
let imp: IMP = imp_implementationWithBlock(block)
method_setImplementation(method, imp)
}
if let method = class_getInstanceMethod(WKContentViewClass, newerSelector) {
let originalImp: IMP = method_getImplementation(method)
let original: NewerClosureType = unsafeBitCast(originalImp, to: NewerClosureType.self)
let block : @convention(block) (Any, UnsafeRawPointer, Bool, Bool, Bool, Any?) -> Void = { (me, arg0, arg1, arg2, arg3, arg4) in
original(me, newerSelector, arg0, !value, arg2, arg3, arg4)
}
let imp: IMP = imp_implementationWithBlock(block)
method_setImplementation(method, imp)
}
}
}
原文地址
https://stackoverflow.com/questions/32449870/programmatically-focus-on-a-form-in-a-webview-wkwebview