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

SwiftUI自定义右键点击事件导致.contextMenu修饰符失效问题

问题原因

你的自定义右键修饰符和原生.contextMenu冲突,核心问题有三个:

  • 透明覆盖视图RightClickListeningView没有配置正确的尺寸自适应和事件命中逻辑,会打乱AppKit原生的事件传递链,导致底层SwiftUI视图无法正常接收右键事件。
  • rightMouseDown方法中手动查找菜单、手动调用menu.popUp的逻辑完全冗余:当前覆盖视图本身没有绑定上下文菜单,永远拿不到正确的menu实例,还会和系统原生的菜单弹出逻辑产生冲突。
  • 你没有明确让透明视图参与事件响应,AppKit默认会跳过无绘制内容的透明视图,导致事件传递行为不可预期。
修复后的完整实现

直接替换你原来的自定义右键相关代码即可:

extension View {
    func onRightClick(handler: @escaping () -> Void) -> some View {
        modifier(RightClickHandler(handler: handler))
    }
}

struct RightClickHandler: ViewModifier {
    let handler: () -> Void
    func body(content: Content) -> some View {
        content.overlay(RightClickListeningViewRepresentable(handler: handler))
    }
}

struct RightClickListeningViewRepresentable: NSViewRepresentable {
    let handler: () -> Void
    func makeNSView(context: Context) -> RightClickListeningView {
        let view = RightClickListeningView(handler: handler)
        // 让自定义视图自动跟随父视图缩放,填满覆盖区域
        view.autoresizingMask = [.width, .height]
        return view
    }
    func updateNSView(_ nsView: RightClickListeningView, context: Context) {}
}

class RightClickListeningView: NSView {
    let handler: () -> Void
    
    init(handler: @escaping () -> Void) {
        self.handler = handler
        super.init(frame: .zero)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func rightMouseDown(with event: NSEvent) {
        // 执行自定义右键逻辑
        handler()
        // 仅调用父类实现,由系统沿响应链自动处理原生contextMenu弹出
        super.rightMouseDown(with: event)
    }
    
    // 重写命中测试,确保透明视图能正常接收范围内的鼠标事件
    override func hitTest(_ point: NSPoint) -> NSView? {
        bounds.contains(point) ? self : nil
    }
}
关键改动说明
  • 移除了所有手动查找、弹出上下文菜单的冗余代码,完全交给系统原生响应链处理,从根源上避免和.contextMenu的冲突。
  • 给自定义NSView添加了尺寸自适应配置,确保它能完整覆盖目标视图区域,不会出现事件接收盲区。
  • 重写hitTest方法,明确透明视图的事件响应范围,避免AppKit默认跳过无绘制内容透明视图的机制导致事件传递异常。

修复后你原来的测试代码即可正常运行:右键时既能触发自定义的打印逻辑,也能正常弹出上下文菜单。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 06:27:14