You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS 16中如何结合原生文本选择手势在WKWebView使用UIEditMenu?

在WKWebView中结合原生文本选择手势使用UIEditMenuInteraction(iOS 16+)

要解决你遇到的「自定义手势与原生文本选择手势冲突」问题,核心思路是利用系统原生的文本选择触发流程,无需手动添加额外手势。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)
        }
    }
}

关键说明

  1. 移除自定义长按手势:WKWebView自带的文本选择手势(长按、拖动)会自动触发系统编辑菜单流程,无需手动添加UILongPressGestureRecognizer,避免手势冲突。
  2. 拦截系统菜单流程:通过UIEditMenuInteractionDelegate的editMenuInteraction(_:menuFor:suggestedActions:)方法,我们可以获取系统提供的原生动作(如复制、定义),并自由合并或替换为自定义菜单。
  3. 与WKWebView交互:通过evaluateJavaScript方法,我们可以获取网页中选中的文本,或对网页内容进行修改(如添加高亮),实现自定义动作的逻辑。

内容的提问来源于stack exchange,提问作者user291334

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 14:40:37