wkwebview 中的 UIMenuItem #selector 方法崩溃

Kar*_*han 5 crash selector uimenuitem wkwebview

UIMenuItem选择器方法在 iOS 11 beta SDK 中崩溃。

-[WKContentViewhighlightText]:无法识别的选择器发送到实例0x7f85df8f3200

方法定义:

func highlightText() 
{
  //
}
Run Code Online (Sandbox Code Playgroud)

UIMenuItem我尝试在WKWebView中添加,

let menuItemHighlight = UIMenuItem.init(title: "Highlight", action: #selector(ContentWebkitView.highlightText))
UIMenuController.shared.menuItems = [menuItemHighlight]
Run Code Online (Sandbox Code Playgroud)

Fré*_*dda 0

好的,我们终于让它适用于 Swift 4:

  1. 在 WKWebView 子类中,添加以下属性和方法:

    // MARK: - Swizzling to avoid responder chain crash    
    var wkContentView: UIView? {
        return self.subviewWithClassName("WKContentView")
    }
    
    
    private func swizzleResponderChainAction() {
        wkContentView?.swizzlePerformAction()
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 然后,向 UIView 添加扩展(我将其放在与 WKWebView 子类相同的文件中,如果您愿意,可以将其设置为 fileprivate)

    // MARK: - Extension used for the swizzling part linked to wkContentView 
    extension UIView {
    
        /// Find a subview corresponding to the className parameter, recursively.
        func subviewWithClassName(_ className: String) -> UIView? {
    
            if NSStringFromClass(type(of: self)) == className {
                return self
            } else {
                for subview in subviews {
                    return subview.subviewWithClassName(className)
                }
            }
            return nil
        }
    
        func swizzlePerformAction() {
            swizzleMethod(#selector(canPerformAction), withSelector: #selector(swizzledCanPerformAction))
        }
    
        private func swizzleMethod(_ currentSelector: Selector, withSelector newSelector: Selector) {
            if let currentMethod = self.instanceMethod(for: currentSelector),
                let newMethod = self.instanceMethod(for:newSelector) {
                let newImplementation = method_getImplementation(newMethod)
                method_setImplementation(currentMethod, newImplementation)
            } else {
                print("Could not find originalSelector")
            }
        }
    
        private func instanceMethod(for selector: Selector) -> Method? {
            let classType = type(of: self)
            return class_getInstanceMethod(classType, selector)
        }
    
        @objc private func swizzledCanPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
            return false
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

现在 UIMenuItem 按预期工作: UIMenuItem 截图

但老实说,这真的感觉像是一个黑客攻击,我希望苹果能够解决这个问题:-/

感谢 Stephan Heilner 的回答:/sf/answers/3008980901/