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

如何在macOS的SwiftUI中检测单次鼠标按下与抬起事件

解决SwiftUI Rectangle鼠标按下/抬起仅触发一次的问题

你的代码问题在于使用了NSEvent.addLocalMonitorForEvents,这是全局监听整个应用的鼠标事件,而且每次视图onAppear都会重复注册监听,导致同一事件被多个监听器处理,出现多次打印。同时该监听不区分是否点击在目标Rectangle上,只要是左鼠标操作就会触发。

下面是两种针对Rectangle视图的解决方案,确保仅在点击该视图时触发一次按下/抬起事件:

方法1:使用SwiftUI DragGesture(推荐)

利用DragGesture并设置最小触发距离为0,按下时触发onChanged,抬起时触发onEnded,且仅作用于当前Rectangle:

var body: some View {
    Rectangle()
        .gesture(
            DragGesture(minimumDistance: 0)
                .onChanged { _ in
                    print("mouse down")
                }
                .onEnded { _ in
                    print("mouse up")
                }
        )
}

方法2:使用NSViewRepresentable封装NSView

通过原生NSView的事件处理,精准控制视图内的鼠标事件:

struct ClickableRectangle: NSViewRepresentable {
    func makeNSView(context: Context) -> NSView {
        let view = NSView()
        view.wantsLayer = true
        view.layer?.backgroundColor = NSColor.blue.cgColor // 自定义背景色,对应Rectangle
        // 绑定事件处理器到Coordinator
        view.target = context.coordinator
        view.action = #selector(Coordinator.handleMouseEvent(_:))
        return view
    }
    
    func updateNSView(_ nsView: NSView, context: Context) {}
    
    func makeCoordinator() -> Coordinator {
        Coordinator()
    }
    
    class Coordinator: NSObject {
        private var isMouseDown = false
        
        @objc func handleMouseEvent(_ event: NSEvent) {
            switch event.type {
            case .leftMouseDown where !isMouseDown:
                print("mouse down")
                isMouseDown = true
            case .leftMouseUp where isMouseDown:
                print("mouse up")
                isMouseDown = false
            default:
                break
            }
        }
    }
}

// 使用示例
var body: some View {
    ClickableRectangle()
        .frame(width: 200, height: 200)
}

内容的提问来源于stack exchange,提问作者Sébastien REMY

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 19:41:00