Reputation: 219
I use UIMenuController when presenting my custom menu for the selected text on my WKWebview. But it is now deprecated on iOS 16, and get the following error
[Text] Using UIMenuController to add items into text menus is deprecated. Please implement the UITextInput API editMenuForTextRange:suggestedActions: instead.
[EditMenuInteraction] The edit menu ... did not have performable commands and/or actions; ignoring present.
And now I cant find any documentation on how to customize the menu on wkwebview.
This is what I am trying to present on the menu.
How can you customize the menu on the selected text on wkwebview?
I tried adding UITextInput, but it requires to conform to a bunch of protocols.
Upvotes: 3
Views: 2551
Reputation: 9131
In the view controller that contains the WKWebView
control, override the buildMenu
method to add a custom context menu item, like this:
override func buildMenu(with builder: any UIMenuBuilder) {
let customMenuItem = UIAction(title: "Custom Title", image: UIImage(systemName: "star")) { action in
// Handle menu item action here
}
let menu = UIMenu(title: String(), image: nil, identifier: nil, options: .displayInline, children: [customMenuItem])
builder.insertSibling(menu, afterMenu: .standardEdit) // Or any other system menu
super.buildMenu(with: builder)
}
Works with iOS 16 or newer
Upvotes: 3
Reputation: 2268
This isn't possible just yet, but I think Apple is planning to add APIs for UIEditMenuInteraction
soon. This is what I found in the WebKit source (mind the WK_IOS_TBA
availability specifier):
/**
* @abstract Called when the web view is about to present its edit menu.
*
* @param webView The web view displaying the menu.
* @param animator Appearance animator. Add animations to this object to run them alongside the appearance transition.
*/
- (void)webView:(WKWebView *)webView willPresentEditMenuWithAnimator:(id<UIEditMenuInteractionAnimating>)animator WK_API_AVAILABLE(ios(WK_IOS_TBA));
/**
* @abstract Called when the web view is about to dismiss its edit menu.
*
* @param webView The web view displaying the menu.
* @param animator Dismissal animator. Add animations to this object to run them alongside the dismissal transition.
*/
- (void)webView:(WKWebView *)webView willDismissEditMenuWithAnimator:(id<UIEditMenuInteractionAnimating>)animator WK_API_AVAILABLE(ios(WK_IOS_TBA));
UPDATE: These methods are showing up in the WKUIDelegate
docs too now:
Upvotes: 2
Reputation: 73
I faced the same issue while presenting my custom menu in webview in iOS 16. I implemented the following method and removed all non-required menu items as following and it was good to go:
open override func buildMenu(with builder: UIMenuBuilder) {
if #available(iOS 16.0, *) {
builder.remove(menu: .lookup)
builder.remove(menu: .file)
builder.remove(menu: .edit)
builder.remove(menu: .view)
builder.remove(menu: .window)
builder.remove(menu: .help)
builder.remove(menu: .about)
builder.remove(menu: .preferences)
builder.remove(menu: .services)
builder.remove(menu: .hide)
builder.remove(menu: .quit)
builder.remove(menu: .newScene)
builder.remove(menu: .openRecent)
builder.remove(menu: .close)
builder.remove(menu: .print)
builder.remove(menu: .document)
builder.remove(menu: .undoRedo)
builder.remove(menu: .standardEdit)
builder.remove(menu: .find)
builder.remove(menu: .replace)
builder.remove(menu: .share)
builder.remove(menu: .textStyle)
builder.remove(menu: .spelling)
builder.remove(menu: .spellingPanel)
builder.remove(menu: .spellingOptions)
builder.remove(menu: .substitutions)
builder.remove(menu: .substitutionsPanel)
builder.remove(menu: .substitutionOptions)
builder.remove(menu: .transformations)
builder.remove(menu: .speech)
builder.remove(menu: .learn)
builder.remove(menu: .format)
builder.remove(menu: .font)
builder.remove(menu: .textSize)
builder.remove(menu: .textColor)
builder.remove(menu: .textStylePasteboard)
builder.remove(menu: .text)
builder.remove(menu: .writingDirection)
builder.remove(menu: .alignment)
builder.remove(menu: .toolbar)
builder.remove(menu: .sidebar)
builder.remove(menu: .fullscreen)
builder.remove(menu: .minimizeAndZoom)
builder.remove(menu: .bringAllToFront)
}
super.buildMenu(with: builder)
}
Hope this helps, Cheers
Upvotes: 5