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

SwiftUI中使用UIEditMenuInteraction自定义WebView文本菜单失败求助

在SwiftUI的WKWebView中实现选中文本自定义菜单

问题分析

你的代码无法触发自定义菜单的核心原因有两点:

  • 代理方法editMenuInteraction(_:menuFor:suggestedActions:)被标记为private,系统无法调用该代理逻辑
  • WKWebView的默认文本菜单优先级较高,需要确保UIEditMenuInteraction能正确接管菜单展示

修改后的完整代码

import SwiftUI
import WebKit

struct ContentView: View {
    var body: some View {
        WebView(url: URL(string: "https://www.google.com")!)
    }
}

struct WebView: UIViewRepresentable {
    let url: URL
    
    func makeCoordinator() -> Coordinator {
        Coordinator()
    }
    
    class Coordinator: NSObject, WKNavigationDelegate, UIEditMenuInteractionDelegate {
        // 移除private修饰符,让系统能调用代理方法
        func editMenuInteraction(_ interaction: UIEditMenuInteraction,
                                 menuFor configuration: UIEditMenuConfiguration,
                                 suggestedActions: [UIMenuElement]) -> UIMenu? {
            let customActions = [
                UIAction(title: "菜单选项1") { _ in
                    print("点击菜单选项1")
                },
                UIAction(title: "菜单选项2") { _ in
                    print("点击菜单选项2")
                },
                UIAction(title: "菜单选项3") { _ in
                    print("点击菜单选项3")
                }
            ]
            // 返回自定义菜单,也可以结合suggestedActions保留系统默认选项
            return UIMenu(title: "自定义菜单", children: customActions)
        }
        
        // 可选:确保菜单交互能响应文本选择
        func editMenuInteraction(_ interaction: UIEditMenuInteraction,
                                 targetRectFor configuration: UIEditMenuConfiguration) -> CGRect {
            return configuration.targetRect
        }
    }
    
    func makeUIView(context: Context) -> WKWebView {
        let webConfiguration = WKWebViewConfiguration()
        // 禁用链接预览,避免干扰自定义菜单触发
        webConfiguration.allowsLinkPreview = false
        
        let webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.isUserInteractionEnabled = true
        webView.navigationDelegate = context.coordinator
        
        // 添加菜单交互并设置代理
        let menuInteraction = UIEditMenuInteraction(delegate: context.coordinator)
        webView.addInteraction(menuInteraction)
        
        return webView
    }
    
    func updateUIView(_ uiView: WKWebView, context: Context) {
        let request = URLRequest(url: url)
        uiView.load(request)
    }
}

关键修改说明

  1. 移除代理方法的private修饰符:原代码中editMenuInteraction方法是私有方法,系统无法触发代理逻辑,移除后才能让自定义菜单代码生效。
  2. 配置WKWebViewConfiguration:禁用allowsLinkPreview,避免默认的链接预览菜单干扰自定义菜单的触发。
  3. 可选补充代理方法:添加editMenuInteraction(_:targetRectFor:)确保菜单在正确的位置展示。

扩展说明

如果需要保留系统默认菜单选项,只需将自定义动作和suggestedActions合并:

var combinedActions = suggestedActions
combinedActions.append(contentsOf: customActions)
return UIMenu(title: "", children: combinedActions)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 20:13:06