In iOS 16 UIMenuController
is deprecated. Instead, we should use UIEditMenuInteraction
. In the WWDC notes I found simple example how to use editMenu
in UITextView
with native gestures:
@available(iOS 16.0, *)
class ViewController: UIViewController, UITextViewDelegate {
@IBOutlet weak var myTextView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
myTextView.delegate = self
}
func textView(_ textView: UITextView, editMenuForTextIn range: NSRange, suggestedActions: [UIMenuElement]) -> UIMenu? {
var additionalActions: [UIMenuElement] = []
if textView.selectedRange.length > 0 {
let highlightAction = [UIAction(title: "Highlight") { _ in
print("Highlight")
}]
additionalActions.append(contentsOf:highlightAction)
}
let selectAction = [UIAction(title: "Select") { _ in
print("Select")
}]
additionalActions.append(contentsOf:selectAction)
return UIMenu(children: additionalActions)
}
}
But how to use editMenu
for text selections in WKWebView
with native gestures?
I started experimenting with WKWebView
and wrote this code:
@available(iOS 16.0, *)
class MenuViewController: UIViewController, UIEditMenuInteractionDelegate, WKNavigationDelegate {
@IBOutlet weak var myWebView: WKWebView!
var editMenuInteraction: UIEditMenuInteraction?
override func viewDidLoad() {
super.viewDidLoad()
setupEditMenuInteraction()
setupWKWebView()
}
func setupEditMenuInteraction() {
editMenuInteraction = UIEditMenuInteraction(delegate: self)
myWebView.addInteraction(editMenuInteraction!)
let longPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(_:)))
myWebView.addGestureRecognizer(longPressGestureRecognizer)
}
@objc func handleLongPress(_ gestureRecognizer: UILongPressGestureRecognizer) {
guard gestureRecognizer.state == .began else { return }
let configuration = UIEditMenuConfiguration(
identifier: "textViewEdit",
sourcePoint: gestureRecognizer.location(in: myWebView)
)
editMenuInteraction?.presentEditMenu(with: configuration)
}
func editMenuInteraction(_ interaction: UIEditMenuInteraction, menuFor configuration: UIEditMenuConfiguration, suggestedActions: [UIMenuElement]) -> UIMenu? {
var actions = suggestedActions
let customMenu = UIMenu(title: "", options: .displayInline, children: [
UIAction(title: "menuItem1") { _ in
print("menuItem1")
},
UIAction(title: "menuItem2") { _ in
print("menuItem2")
},
UIAction(title: "menuItem3") { _ in
print("menuItem3")
}
])
actions.append(customMenu)
return UIMenu(children: customMenu.children)
}
}
This code works fine but the problem is that UILongPressGestureRecognizer
is not what I need. I need to show editMenu
after text is selected like native select gesture. What type of gesture should I use instead of UILongPressGestureRecognizer
? Because now in my WKWebView
I call editMenu
with native text select gesture and my editMenu
with long tap gesture. It's not very good solution.