Search code examples
swiftswiftuiwkwebviewuimenucontrolleruimenuitem

SwiftUI : custom pop menu in WKWebView


In My Swift project, I use a wkWebView to display HTML content retrieved from a webservice. Everything works. I would like to go further and allow the user to report a fault through the menu when part of the text is selected.

Instead of proposing "copy, cut and paste", I would only like "Copy" + "Report a fault".

The button would have the action of opening the mailbox and inserting the selected text there.

I don't know how to do it. I'm only able to disable the "cut"/"paste" buttons and only keep "copy".

My code :

struct articleWebView: UIViewRepresentable  {
    
     ...
    
    func makeUIView(context: Context) -> WKWebView {

        let WKWebView = CustomWKWebView()
        return WKWebView()
    }
    
    
    
    func updateUIView(_ uiView: WKWebView, context: Context) {
    
          ...
     }
}

class CustomWKWebView: WKWebView {

 //we deactivate everything except "copy" 
 override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        switch action {
        case #selector(copy(_:)):
            return true

        default:
            return false
        }
    }

}

Thank you in advance


Solution

  • it's been 6 months but here is the answer (works perfectly before iOS 16. With iOS 16 the function is deprecated but still works)

    everything happens in canPerformAction

    class CustomWKWebView: WKWebView{
        
    
    
        override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
    
                let menu = UIMenuController.shared
                menu.shared.menuItems = []
                let newInstanceItem = UIMenuItem(title: " My Custom Action", action:#selector(myCustomAction))
                menu.menuItems = [newInstanceItem]
                menu.update()
                if action == #selector(copy(_:)) || action == #selector(selectAll(_:)) || action == #selector(myCustomAction)){
    
                    return true
                }
                return false
    
        }
    
    
    
        @objc func myCustomAction() {
            // your code
    
        }
    
    }