我有一个仅限状态栏项目的应用程序,我试图在mouseOver上显示一个面板。我有自定义状态项(和关联的视图)连接和工作,但跟踪rect只接收每十几个启动事件。这让我相信在某个地方发生了竞争状况,但我找不到它。在我的自定义状态栏项视图中:
- (id)initWithStatusItem:(NSStatusItem *)statusItem {
CGFloat itemWidth = [statusItem length];
CGFloat itemHeight = [[NSStatusBar systemStatusBar] thickness];
NSRect itemRect = NSMakeRect(0.0, 0.0, itemWidth, itemHeight);
NSLog(@"itemRect: %@", NSStringFromRect(itemRect));
if ((self = [super initWithFrame:itemRect])) {
_statusItem = statusItem;
_statusItem.view = self;
NSTrackingAreaOptions options = NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingActiveAlways;
NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:itemRect
options:options
owner:self
userInfo:nil];
[self addTrackingArea:trackingArea];
[self.window setIgnoresMouseEvents:NO];
[self.window setAcceptsMouseMovedEvents:YES];
self.wantsLayer = YES;
}
return self;
}
- (void)mouseEntered:(NSEvent *)theEvent {
[[NSNotificationCenter defaultCenter] postNotificationName:UAStatusItemMouseEnteredNotification object:nil];
}
- (void)mouseExited:(NSEvent *)theEvent {
[[NSNotificationCenter defaultCenter] postNotificationName:UAStatusItemMouseExitedNotification object:nil];
}
在大多数发布时,应用都不会响应跟踪鼠标事件,但每隔一段时间,mouseEntered:
和mouseExited:
方法都会被正确调用,这让我很困惑。这里发生了什么,我做错了什么?
编辑07/17/2012
我根据@ Streams的答案修改了代码,但看到同样的问题:
- (id)initWithStatusItem:(NSStatusItem *)statusItem {
CGFloat itemWidth = [statusItem length];
CGFloat itemHeight = [[NSStatusBar systemStatusBar] thickness];
NSRect itemRect = NSMakeRect(0.0, 0.0, itemWidth, itemHeight);
NSLog(@"itemRect: %@", NSStringFromRect(itemRect));
if ((self = [super initWithFrame:itemRect])) {
_statusItem = statusItem;
_statusItem.view = self;
[self updateTrackingAreas];
[self.window setIgnoresMouseEvents:NO];
[self.window setAcceptsMouseMovedEvents:YES];
self.wantsLayer = YES;
}
return self;
}
- (void)updateTrackingAreas {
if (self.trackingArea)
[self removeTrackingArea:self.trackingArea];
[super updateTrackingAreas];
self.trackingArea = [[NSTrackingArea alloc] initWithRect:CGRectZero
options:NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingInVisibleRect | NSTrackingActiveAlways
owner:self
userInfo:nil];
[self addTrackingArea:self.trackingArea];
}
编辑07/18/2012
这是一个准系统sample project,它使用一个众所周知的github项目(由@Stream编写)来显示问题。如果有的话,它无法可靠地接收鼠标悬停事件。
答案 0 :(得分:2)
我打开了一个DTS请求让Apple看看这个。以下是回复:
...启动应用时,您在Xcode中使用全屏。一世 在[之前]没有这样做,但我现在可以重现这个问题。从我能做到的 告诉它只有在你的应用程序从全屏模式启动时才会发生 Xcode中。您的用户不会以这种方式启动应用。这是一个 AppKit的fullScreen模式存在问题,而不一定是你的 代码。
答案 1 :(得分:0)
我认为您应该只在-[NSView updateTrackingAreas]
管理跟踪区域。例如:
- (void)updateTrackingAreas
{
if (_trackingArea) {
[self removeTrackingArea:_trackingArea];
}
[super updateTrackingAreas];
NSTrackingAreaOptions options = (NSTrackingMouseEnteredAndExited |
NSTrackingMouseMoved |
NSTrackingInVisibleRect |
NSTrackingActiveAlways);
_trackingArea = [[NSTrackingArea alloc] initWithRect:CGRectZero
options:options
owner:self
userInfo:nil];
[self addTrackingArea:_trackingArea];
}