iOS 16中如何结合原生文本选择手势在WKWebView使用UIEditMenu?
要解决你遇到的「自定义手势与原生文本选择手势冲突」问题,核心思路是利用系统原生的文本选择触发流程,无需手动添加额外手势。WKWebView的原生选择手势(长按、拖动选中文本)会自动触发编辑菜单的展示逻辑,我们只需通过UIEditMenuInteraction拦截这一流程,替换为自定义菜单即可。
修正后的实现代码
@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!) } func setupWKWebView() { myWebView.navigationDelegate = self // 加载测试网页 let testHTML = "<html><body><p>测试文本:长按选中后将显示自定义编辑菜单</p></body></html>" myWebView.loadHTMLString(testHTML, baseURL: nil) } // 拦截系统菜单,替换/合并自定义菜单 func editMenuInteraction(_ interaction: UIEditMenuInteraction, menuFor configuration: UIEditMenuConfiguration, suggestedActions: [UIMenuElement]) -> UIMenu? { // 保留系统原生动作(如复制、定义),并添加自定义动作 var combinedActions = suggestedActions // 构建自定义菜单组 let customActions = [ UIAction(title: "高亮选中内容") { [weak self] _ in self?.applyHighlightToSelection() }, UIAction(title: "分享选中内容") { [weak self] _ in self?.shareSelectedText() } ] let customMenu = UIMenu(title: "", options: .displayInline, children: customActions) combinedActions.append(customMenu) // 返回合并后的菜单(若需完全替换原生菜单,直接返回UIMenu(children: customActions)即可) return UIMenu(children: combinedActions) } // 自定义动作:给选中文本添加高亮 private func applyHighlightToSelection() { myWebView.evaluateJavaScript(""" const selection = window.getSelection(); if (selection.rangeCount > 0) { const range = selection.getRangeAt(0); const highlightSpan = document.createElement('span'); highlightSpan.style.backgroundColor = '#ffeb3b'; range.surroundContents(highlightSpan); selection.removeAllRanges(); } """) } // 自定义动作:分享选中的文本 private func shareSelectedText() { myWebView.evaluateJavaScript("window.getSelection().toString()") { [weak self] result, error in guard let selectedText = result as? String, !selectedText.isEmpty else { return } let activityVC = UIActivityViewController(activityItems: [selectedText], applicationActivities: nil) self?.present(activityVC, animated: true) } } }
关键说明
- 移除自定义长按手势:WKWebView自带的文本选择手势(长按、拖动)会自动触发系统编辑菜单流程,无需手动添加
UILongPressGestureRecognizer,避免手势冲突。 - 拦截系统菜单流程:通过
UIEditMenuInteractionDelegate的editMenuInteraction(_:menuFor:suggestedActions:)方法,我们可以获取系统提供的原生动作(如复制、定义),并自由合并或替换为自定义菜单。 - 与WKWebView交互:通过
evaluateJavaScript方法,我们可以获取网页中选中的文本,或对网页内容进行修改(如添加高亮),实现自定义动作的逻辑。
内容的提问来源于stack exchange,提问作者user291334
相关产品推荐
相关产品推荐

