WKWebView自动弹出键盘和隐藏输入附属视图(inputAccessoryView)

自动弹出键盘

在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代码,可以看这里这里



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值