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

如何从PKCanvasView中移除UIEditMenuInteraction?

如何从PKCanvasView中移除UIEditMenuInteraction?

嘿,我太懂你这种头疼的情况了!iOS17更新后,PKCanvasView突然冒出来的系统编辑菜单确实会和咱们自己做的自定义菜单打架,我之前也踩过这个坑,给你分享几个亲测有效的解决办法:

  • 直接移除系统交互(最彻底)
    系统的编辑菜单是通过UIEditMenuInteraction实现的,咱们可以直接遍历PKCanvasView的交互列表,找到它然后移除掉。这种方法适合完全不需要任何系统菜单的场景,一步到位:

    // 可以在PKCanvasView初始化完成后,或者viewDidLoad方法里执行这段代码
    canvasView.interactions.forEach { interaction in
        if interaction is UIEditMenuInteraction {
            canvasView.removeInteraction(interaction)
        }
    }
    

    要是嫌遍历麻烦,也可以用更简洁的写法:

    canvasView.interactions.removeAll { $0 is UIEditMenuInteraction }
    
  • 通过代理拦截菜单展示(更灵活)
    如果你之后可能需要保留部分系统菜单功能,或者想更精细地控制菜单展示,那可以给系统的UIEditMenuInteraction设置代理,通过代理方法拦截菜单的生成:

    // 让你的ViewController遵守UIEditMenuInteractionDelegate协议
    class YourCanvasViewController: UIViewController, UIEditMenuInteractionDelegate {
        override func viewDidLoad() {
            super.viewDidLoad()
            
            // 找到PKCanvasView上的UIEditMenuInteraction并设置代理
            if let editMenuInteraction = canvasView.interactions.first(where: { $0 is UIEditMenuInteraction }) as? UIEditMenuInteraction {
                editMenuInteraction.delegate = self
            }
        }
    
        func editMenuInteraction(_ interaction: UIEditMenuInteraction, menuForConfiguration configuration: UIEditMenuConfiguration, suggestedActions: [UIMenuElement]) -> UIMenu? {
            // 返回nil就会阻止系统菜单弹出,也可以在这里返回你自己的自定义菜单
            return nil
        }
    }
    

    这种方法的好处是,之后如果想调整菜单内容,只需要修改这个代理方法的返回值就行,不用大改代码。

  • SwiftUI场景下的处理
    要是你是在SwiftUI里使用PKCanvasView,那可以通过UIViewRepresentable包装的时候处理:

    struct CustomCanvasView: UIViewRepresentable {
        func makeUIView(context: Context) -> PKCanvasView {
            let canvasView = PKCanvasView()
            // 直接移除系统编辑菜单交互
            canvasView.interactions.removeAll { $0 is UIEditMenuInteraction }
            return canvasView
        }
    
        func updateUIView(_ uiView: PKCanvasView, context: Context) {}
    }
    

你可以根据自己的需求选合适的方法,我当时用的是第一种直接移除的方式,简单粗暴又有效😉

备注:内容来源于stack exchange,提问作者jakob witsch

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 11:24:36