自动弹出键盘
在UIWebView中,有一个属性keyboardDisplayRequiresUserAction,设置为NO时就可以在页面刚加载时直接弹出键盘;在WKWebView中,是没有这个属性的,如果要实现类似的功能,就必须替换WKWebView中相应的方法,代码如下:
static void (*originalIMP)(id self, SEL _cmd, void* arg0, BOOL arg1, BOOL arg2, id arg3) = NULL;
void interceptIMP (id self, SEL _cmd, void* arg0, BOOL arg1, BOOL arg2, id arg3) {
originalIMP(self, _cmd, arg0, TRUE, arg2, arg3);
}
+(void)wkWebViewShowKeybord {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class cls = NSClassFromString(@"WKContentView");
SEL originalSelector = NSSelectorFromString(@"_startAssistingNode:userIsInteracting:blurPreviousNode:userObject:");
Method originalMethod = class_getInstanceMethod(cls, originalSelector);
IMP impOvverride = (IMP) interceptIMP;
originalIMP = (void *)method_getImplementation(originalMethod);
method_setImplementation(originalMethod, impOvverride);
});
}
然后调用函数wkWebViewShowKeybord,就可以在加载页面的时候直接显示键盘了;需要特别注意的是,该函数只能调用一次,否则会导致循环调用,程序崩溃。或者为WKWebView添加扩展属性和方法,然后直接设置属性即可,如下:原文内容请看这里
typealias ClosureType = @convention(c) (Any, Selector, UnsafeRawPointer, Bool, Bool, Any) -> Void
extension WKWebView{
var keyboardRequiresUserInteraction: Bool {
get {
return false
} set {
if newValue == true {
setKeyboardRequiresUserInteraction()
}
}
}
func setKeyboardRequiresUserInteraction() {
let sel: Selector = sel_getUid("_startAssistingNode:userIsInteracting:blurPreviousNode:userObject:")
let WKContentView: AnyClass = NSClassFromString("WKContentView")!
let method = class_getInstanceMethod(WKContentView, sel)
let originalImp: IMP = method_getImplementation(method!)
let original: ClosureType = unsafeBitCast(originalImp, to: ClosureType.self)
let block : @convention(block) (Any, UnsafeRawPointer, Bool, Bool, Any) -> Void = {(me, arg0, arg1, arg2, arg3) in
original(me, sel, arg0, true, arg2, arg3)
}
let imp: IMP = imp_implementationWithBlock(block)
method_setImplementation(method!, imp)
}
}
键盘虽然出现了,但是又出现了另外一个问题,那就是键盘的inputAccessoryView,如下图:
点击Done,可以隐藏键盘,但是现在我不想显示该inputAccessoryView,那么怎么隐藏呢,代码如下:
final class FauxBarHelper: NSObject {
@objc var inputAccessoryView: AnyObject? { return nil }
func removeInputAccessoryView(webView: WKWebView) {
var targetView: UIView? = nil
for view in webView.scrollView.subviews {
if String(describing: type(of: view)).hasPrefix("WKContent") {
targetView = view
}
}
guard let target = targetView else { return }
let noInputAccessoryViewClassName = "\(target.superclass!)_NoInputAccessoryView"
var newClass: AnyClass? = NSClassFromString(noInputAccessoryViewClassName)
if newClass == nil {
let targetClass: AnyClass = object_getClass(target)!
newClass = objc_allocateClassPair(targetClass, noInputAccessoryViewClassName.cString(using: String.Encoding.ascii)!, 0)
}
let originalMethod = class_getInstanceMethod(FauxBarHelper.self, #selector(getter: FauxBarHelper.inputAccessoryView))
class_addMethod(newClass!.self, #selector(getter: FauxBarHelper.inputAccessoryView), method_getImplementation(originalMethod!), method_getTypeEncoding(originalMethod!))
object_setClass(target, newClass!)
}
}
现在只需要创建FauxBarHelper类实例对象,然后调用removeInputAccessoryView方法,传入对应的webView即可,代码原文地址,如果需要OC代码,可以看这里和这里。