如何使用CALayer在NSView上实现鼠标点击?

时间:2011-03-21 14:51:35

标签: cocoa core-animation mouseevent calayer nswindow

我有一个圆形的自定义无边界NSWindow。为此,我使用自定义NSView绘制一个实心圆圈。

鼠标点击窗口内容中的透明像素 直接浏览窗口,看看它背后的应用程序是什么。我的应用程序拦截了填充圆圈内的点击次数。到目前为止一切都很好。

问题是,使用以下行,上述行为会发生变化,并且窗口内容rect内的所有点击都会被拦截,是否为透明像素:

[circleView setWantsLayer:YES];

有没有办法让CALayer个实例的透明像素点击通过窗口/视图/图层到它后面的应用程序?

它基本上与下面描述的完全相同的问题(只是解决方案在所有情况下都不起作用,因为它不支持动画):

http://www.cocoabuilder.com/archive/cocoa/235281-clicking-through-nsview-with-calayers.html

3 个答案:

答案 0 :(得分:0)

我不完全确定这是否适用于图层支持的视图,但可能的解决方案是覆盖圆视图子类上的- (NSView *)hitTest:(NSPoint)aPoint并检查aPoint是否位于圆的路径内。如果它在圈外,则从该方法返回nil会导致点击通过。

答案 1 :(得分:0)

使用CGPath的CAShapeLayer可以使用,或者您可以创建CAShapeLayer作为内容层的掩码。

答案 2 :(得分:0)

当您在 CALayer 内创建 NSView 时,您可以向 Views 支持层询问其层层次结构中接收器的最远后代QuartzCore 中的 CALayers 也有一个 hitTest: 方法。

一旦你在这一点上捕捉到一个图层,你可以要求你的 name 或 CALayer 子类的给定 CALayer 属性,以防你有多个 CALayer 并且需要知道它们中的哪一个被击中。
CALayers 没有 .tag 属性。

-(NSView *)hitTest:(NSPoint)p {
    __kindof CALayer *catched = [self.layer hitTest:point];
    NSString *className = NSStringFromClass([catched class]);
    NSLog(@"x%0.1f y%0.1f class:%@ name:%@", p.x, p.y, className, catched.name);
    return [super hitTest:p];
}

注意:如果没有找到图层,结果可能是 null