ios webview自定义弹出框 UIMenuController

webView弹出UIMenuController是系统自带的一个功能,有时候我们需要自己实现自定义的功能,那么我们改怎么做呢。然而我们用的最多的就是WKWebView,对于UIWebView苹果已经舍弃了,现在我们只讨论WKWebView的用法。

实现的方法是基于swift 4.2。我们要实现弹出系统的UIMenuController,需要以下几步:

  • 为当前的controller设置可以第一响应者。
    override var canBecomeFirstResponder: Bool{
        return true;
    }
  • 重写父类的canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool
    override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        return true;
    }

做到这两步我们会看到效果如下:

ios webview自定义弹出框 UIMenuController

这是系统弹出的UIMenuController菜单,我们现在需要自定义菜单,并屏蔽掉系统的菜单。

我们需要重新实现 canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool方法。

    override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        if action == #selector(searchItem) {
            return true;
        }
        return false;
    }

 我们需要判断action是不是我们自定义的,若是是就返回true,否则返回false。并且我们需要在viewDidLoad方法里实现自定义的菜单:

let ctrl = UIMenuController.shared;
let shareItem = UIMenuItem(title: "自定义搜索菜单", action: #selector(searchItem));
ctrl.menuItems = [shareItem];
ctrl.setMenuVisible(true, animated: false);

这时候我们会发现。如下的效果:

ios webview自定义弹出框 UIMenuController

 

又多出来几个系统菜单,这是系统一个bug,我们改怎么办呢。我们需要添加一下代码来完善功能。

override var canResignFirstResponder: Bool{
    return false;
}

这样写就轻松的解决了,我们有时候是只想在某个界面需要显示自定义的,那么这个时候我们会发现不需要显示自定义的界面也会显示我们这个添加的菜单。那是因为这个禁止取消了第一响应,其他的就不能作为第一响应者,所以我们需要在这个页面消失的时候,可以取消第一响应者。我们需要这样写。

override var canResignFirstResponder: Bool{
    if dismiss {
        return true;
    }
    return false;
}

这样就完美解决了。

我们需要获取选中的文字。那么我们需要调用一下方式可以获取:

let jsCript = "window.getSelection().toString()"
webKit.evaluateJavaScript(jsCript) { (result,
error) in
    guard let strl = result as? String else{
        print("error =\(error)");
        return;
    }
    print("reuslt =\(strl)")
};

到此,我们可以轻松的实现自定义的菜单了。每天进步一点点,多年后你会感谢今天的你。