如何从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
相关产品推荐
相关产品推荐

