iOS-Native端禁用WebView上的menu item
2018-11-13 本文已影响0人
转岗做JAVA
举个例子
项目中的webView页面有可能需要禁用全选功能,可以在h5端实现,也可以通过native实现。native端的思路是先找到实现了selectAll(_:)
方法的View,然后通过method swizzling修改View实现的canPerformAction(_:withSender:)
方法,使其不响应selectAll(_:)
方法。下面的代码展示如何通过native端禁用全选功能:
//使用BFS算法查找实现了selectAll方法的视图。对结果进行测试后得出:
//1.UIWebView中是由UIWebBrowserView控制
//2.WKWebView中是由WKContentView控制
func findSelectAllActionViews() -> [UIView] {
var queue = [UIView]()
queue.append(wkWebView)
var views = [UIView]()
while queue.count > 0 {
let subView = queue.removeFirst()
if subView.responds(to: #selector(selectAll(_:))) {
views.append(subView)
}
queue.append(contentsOf: subView.subviews)
}
return views
}
// 线上使用时直接对UIWebBrowserView或WKContentView进行替换。
func disableViewSelectAllAction() {
let className1: AnyClass = NSClassFromString("UIWebBrowserView")!
let className2: AnyClass = NSClassFromString("WKContentView")!
self.findSelectAllActionViews().forEach { actionView in
if actionView.isKind(of: className1) || actionView.isKind(of: className2) {
let customSelector = #selector(ct_canPerformAction(_:withSender:))
if let m1 = class_getInstanceMethod(actionView.classForCoder, #selector(canPerformAction(_:withSender:))) ,
let imp = class_getMethodImplementation(self.classForCoder, customSelector),
class_addMethod(actionView.classForCoder, customSelector, imp, method_getTypeEncoding(m1)) {
let m2 = class_getInstanceMethod(actionView.classForCoder, customSelector)!
method_exchangeImplementations(m1, m2)
}
}
}
}
//禁用掉selectAll:方法,其他不禁用。
//效果就是全选不能用,其他的menu item跟以前的逻辑一样
@objc dynamic func ct_canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
return action.description != "selectAll:" && ct_canPerformAction(action, withSender: sender)
}
如果要禁用其他的menu item,也可用同样的方式;禁用所有的menu item的话,直接return false就可以了。