Cocoa 如何使透明的NSView子类处理鼠标事件? 问题
我在透明的Cocoa 如何使透明的NSView子类处理鼠标事件? 问题,cocoa,Cocoa,我在透明的NSWindow上有一个透明的NSView。视图的drawRect:方法在视图上绘制一些内容(NSImages、NSBezierPaths和NSStrings),但部分内容保持透明 单击已绘制的视图区域将调用常用的鼠标事件处理方法(mouseDown:和mouseUp:) 单击透明区域可以聚焦在我的透明窗口后面的任何窗口 我希望使透明区域的部分可单击,以便在视图上绘制的元素之间意外单击不会导致窗口失去焦点 已尝试的解决方案 重写NSView的hitTest:方法。发现只有在单击视图
NSWindow
上有一个透明的NSView
。视图的drawRect:
方法在视图上绘制一些内容(NSImage
s、NSBezierPath
s和NSString
s),但部分内容保持透明
单击已绘制的视图区域将调用常用的鼠标事件处理方法(mouseDown:
和mouseUp:
)
单击透明区域可以聚焦在我的透明窗口后面的任何窗口
我希望使透明区域的部分可单击,以便在视图上绘制的元素之间意外单击不会导致窗口失去焦点
已尝试的解决方案
- 重写
的NSView
方法。发现只有在单击视图的非透明区域时才调用了hitTest:
hitTest:
- 覆盖
的NSView
方法。发现在单击视图的任何部分时未调用此函数opaque祖先
- 在
方法中,用drawRect:
填充部分透明区域,并使用几乎但不完全透明的颜色。这没有效果[NSColor clearColor]
- 使用
类进行实验。这似乎只增加了对NSTrackingArea
、mouseEntered:
、mouseExited:
和mouseMoved:
方法的支持,而不是cursorUpdate:
和mouseUp:
mouseDown:
- (NSView *)hitTest:(NSPoint)aPoint
在NSView SubCass?中,您可以覆盖
NSView
中的hitTest
方法,使其始终返回自身
根据,如果点不在NSView
内,则hitTest
方法将返回用户单击的NSView,或者nil
。在本例中,我将调用[super-hitTest:
,然后仅当结果为nil
(以防自定义视图包含子视图)时才返回当前视图
据我所知,windows的透明部分的单击事件根本不会传递到应用程序,因此任何正常的事件链覆盖(即-hitTest:,-sendEvent:,等等)都无法工作。我能想到的唯一方法就是使用石英事件点击捕捉所有鼠标点击,然后手动确定它们是否位于窗口的透明区域上。坦白地说,这听起来像是一个巨大的皮塔,收获不大。乔治:你提到你试着用几乎但不完全透明的颜色填充食物。在我的测试中,它似乎只有在alpha值高于0.05时才起作用,因此您可能会有这样的运气:
[[NSColor colorWithCalibratedRed:0.01 green:0.01 blue:0.01 alpha:0.05] set];
这是一个丑陋的难题,但它可能足够好,可以避免使用事件点击。我也有同样的问题。看起来
[window setIgnoresMouseEvents:NO]
可以执行此操作
(至少在Lion上。请参阅)您可以使用事件监视器捕捉窗口/视图外的事件。 您可以执行以下操作:
NSView* windowContent = [window contentView];
[windowContent setWantsLayer:YES]
确保背景是透明的:
[[windowContent layer] setBackgroundColor:[[NSColor clearColor] CGColor]];
另一个选择是添加一个透明的背景图像,填充contentView。谢谢Tristan。我之前确实尝试过这个方法,但是我的子类的hitTest:方法在我单击非透明区域之前不会被调用。谢谢James,不幸的是,hitTest:方法在我单击NSView的不透明区域之前不会被调用。谢谢Boaz。我已经看过了活动API,我想你是对的,它太麻烦了!
[[windowContent layer] setBackgroundColor:[[NSColor clearColor] CGColor]];