如何使透明的NSView子类处理鼠标事件?

时间:2009-01-12 15:05:28

标签: cocoa

问题

我在透明的NSView上有一个透明的NSWindow。视图的drawRect:方法会在视图上绘制一些内容(NSImage s,NSBezierPathNSString s),但会使部分内容保持透明。

单击已绘制的视图区域会调用常用的鼠标事件处理方法(mouseDown:mouseUp:)。

单击透明区域可以聚焦透明窗口后面的任何窗口。

我想让部分透明区域可点击,以便在我的视图上绘制的元素之间意外点击不会导致窗口失去焦点。


已尝试解决方案

  • 覆盖NSView的{​​{1}}方法。发现仅在单击视图的非透明区域时才调用hitTest:
  • 覆盖hitTest:的{​​{1}}方法。发现在单击视图的任何部分时未调用此项。
  • 使用NSView方法中的opaqueAncestor填充透明区域的部分,并使用几乎但不太透明的颜色。这没有效果。
  • 使用[NSColor clearColor]类进行实验。这似乎只会添加对drawRect:NSTrackingAreamouseEntered:mouseExited:方法, mouseMoved:和{{1}的支持}}。

7 个答案:

答案 0 :(得分:6)

我遇到了同样的问题。看起来[window setIgnoresMouseEvents:NO]会做到这一点。

(至少狮子会。见http://www.cocoabuilder.com/archive/cocoa/306910-lion-breaks-the-ability-to-click-through-transparent-window-areas-when-the-window-is-resizable.html

答案 1 :(得分:5)

据我所知,单击事件到窗口的透明部分根本没有传递给你的应用程序,所以没有正常的事件链覆盖(即-hitTest:, - sendEvent:等)可以工作。我能想到的唯一方法是使用Quartz Event Taps来捕获所有鼠标点击,然后确定它们是否是手动覆盖窗口的透明区域。坦率地说,这听起来像是一个巨大的PITA而没有太大的收获。

答案 2 :(得分:2)

乔治:你提到你尝试用几乎但不太透明的颜色填充部分。在我的测试中,它似乎只有在alpha值大于0.05时才有效,所以你可能会有这样的运气:

[[NSColor colorWithCalibratedRed:0.01 green:0.01 blue:0.01 alpha:0.05] set];

这是一个丑陋的kludge,但它可能足以避免使用事件点击。

答案 3 :(得分:1)

您是否尝试重写

- (NSView *)hitTest:(NSPoint)aPoint 
你的UIView子类中的

答案 4 :(得分:1)

答案 5 :(得分:0)

您可以覆盖hitTest中的NSView方法,以便它始终返回。

根据NSView documentationhitTest方法将返回用户点击的NSView,如果该点不在nil内,则返回NSView。在这种情况下,我会调用[super hitTest:],然后仅在结果为nil时返回当前视图(以防您的自定义视图包含子视图)。

- (NSView *)hitTest:(NSPoint)aPoint
{
    NSView * clickedView = [super hitTest:aPoint];
    if (clickedView == nil)
    {
        clickedView = self;
    }

    return clickedView;
}

答案 6 :(得分:0)

你可以这样做:

NSView* windowContent = [window contentView];
[windowContent setWantsLayer:YES]

确保背景透明:

[[windowContent layer] setBackgroundColor:[[NSColor clearColor] CGColor]];

另一种选择是添加填充contentView的透明背景图像。