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

