4

How can we use UIEditMenuInteraction in WkWebViewUITextView to customize menu and add more buttons?

Before iOS 16 I was using:

UIMenuController.shared.menuItems = [menuItem1, menuItem2, menuItem3]

in

override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {...}

Thank you

dibs
  • 174
  • 1
  • 12
  • Facing same issue, did you get any solution as of now? – Amit Singh Sep 26 '22 at 07:49
  • No sorry. canPerformAction still works on ios 16 (deprecated) so I still use it. However, there is a bug, the personalized menu does not appear the first time, you have to redo a selection of text for it to work. If I find the solution I will put it on the page – dibs Sep 27 '22 at 15:14

1 Answers1

2

I had the same problem and it took quite a while to find a solution. But, I found I could override buildMenu in MyTextView: UITextView. Here is my code to add a Strikethrough to the menu in iOS 16 and 15

// This works in iOS 16. I removed some menu items I didn't want as well
open override func buildMenu(with builder: UIMenuBuilder) {
    if #available(iOS 16.0, *) {
        builder.remove(menu: .lookup) // Lookup, Translate, Search Web
        //builder.remove(menu: .standardEdit) // Cut, Copy, Paste
        builder.remove(menu: .replace) // Replace
        builder.remove(menu: .share) // Share
        //builder.remove(menu: .textStyle) // Format
        // Add new .textStyle action
        let strikethroughAction = UIAction(title: "Strikethough") { action in self.toggleStrikethrough(action.sender)}
        builder.replaceChildren(ofMenu: .textStyle, from: {
            var children = $0
            children.append(strikethroughAction)
            return children
        })
    }
    super.buildMenu(with: builder)
}
// This is needed for iOS 15
open override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
    if #unavailable(iOS 16.0) {
        let menuController = UIMenuController.shared
        if var menuItems = menuController.menuItems,
           (menuItems.map { $0.title })
            .elementsEqual(["Bold", "Italic", "Underline"]) {
            // The font style menu is about to become visible -- Add a new menu item for strikethrough style
            // Says iOS 16 must use UIEditMenuIteraction instead since UIMenuItem is deprecated in iOS 16
            menuItems.append(UIMenuItem(title: "Strikethrough", action: .toggleStrikethrough))
            menuController.menuItems = menuItems
        }
    }
    return super.canPerformAction(action, withSender: sender)
}

toggleStrikethrough is a new func I created and added to Selector

fileprivate extension Selector {
    static let toggleBoldface = #selector(TextView.MyTextView.toggleBoldface(_:))
    static let toggleItalics = #selector(TextView.MyTextView.toggleItalics(_:))
    static let toggleUnderline = #selector(TextView.MyTextView.toggleUnderline(_:))
    static let toggleStrikethrough = #selector(TextView.MyTextView.toggleStrikethrough(_:))
}

Hope this helps.

Joseph Levy
  • 157
  • 8