如何在iOS/iPadOS的WKWebView中为选中文本添加自定义菜单项?
在WKWebView选中文本的上下文菜单中添加自定义菜单项
要给WKWebView中选中文本的上下文菜单添加自定义项,核心是利用WKUIDelegate的webView(_:contextMenuConfigurationForElement:completionHandler:)方法——这个方法并非只针对链接,同样能处理文本选中场景。以下是具体实现步骤:
1. 配置WKWebView并设置代理
确保你的控制器遵守WKUIDelegate,并将WKWebView的uiDelegate指向当前控制器:
import UIKit import WebKit class ViewController: UIViewController, WKUIDelegate { private var webView: WKWebView! override func viewDidLoad() { super.viewDidLoad() let config = WKWebViewConfiguration() webView = WKWebView(frame: view.bounds, configuration: config) webView.uiDelegate = self // 关键:必须设置此代理 webView.autoresizingMask = [.flexibleWidth, .flexibleHeight] view.addSubview(webView) // 加载测试内容 let testHTML = "<html><body><h3>测试文本</h3><p>选中这段文字,查看上下文菜单</p></body></html>" webView.loadHTMLString(testHTML, baseURL: nil) } }
2. 实现上下文菜单代理方法
在代理方法中,先判断是否有选中的文本,再构建包含自定义项的上下文菜单:
func webView(_ webView: WKWebView, contextMenuConfigurationForElement elementInfo: WKContextMenuElementInfo, completionHandler: @escaping (UIContextMenuConfiguration?) -> Void) { // 仅当存在有效选中文本时,自定义菜单 guard let selectedText = elementInfo.text, !selectedText.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else { // 无选中文本,交给系统默认处理 completionHandler(nil) return } // 创建菜单配置 let menuConfig = UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { suggestedActions in // 定义自定义菜单项 let customAction = UIAction(title: "处理选中文本", image: UIImage(systemName: "textformat")) { _ in // 这里编写你的自定义逻辑,比如使用选中的文本 print("用户选中的文本:\(selectedText)") // 示例:弹出提示框展示选中内容 let alert = UIAlertController(title: "选中的文本", message: selectedText, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "确定", style: .default)) self.present(alert, animated: true) } // 保留系统默认菜单项(如复制、定义),并添加自定义项 let defaultMenuItems = suggestedActions ?? UIMenu() return UIMenu(title: "", children: defaultMenuItems.children + [customAction]) } completionHandler(menuConfig) }
关键注意事项
elementInfo.text直接返回用户选中的文本内容,需注意过滤空文本(比如仅选中空格的情况)。- 如果不需要保留系统默认菜单,直接返回仅包含自定义项的
UIMenu即可。 - 若你的项目使用Objective-C,逻辑类似,只需将Swift语法转换为OC对应的block和API。
内容的提问来源于stack exchange,提问作者Ely
相关产品推荐
相关产品推荐

