У меня есть приложение только для элемента строки состояния, которое я пытаюсь заставить отображать панель при наведении курсора мыши. У меня есть настраиваемый элемент статуса (и связанное с ним представление), подключенный и работающий, но прямоугольник отслеживания получает события только при каждой дюжине или около того запусков. Это заставляет меня поверить, что где-то происходит состояние гонки, но я не могу его найти. В моем пользовательском представлении элемента строки состояния:
- (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:
вызываются правильно, что полностью сбивает меня с толку. Что здесь происходит и что я делаю неправильно?
EDIT 17/07/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];
}
РЕДАКТИРОВАТЬ 18.07.2012
Вот базовая версия пример проекта, который использует хорошо известный проект github (написанный @Stream) для демонстрации проблемы. Он не может надежно получать события наведения мыши, если вообще получает.