У меня есть подкласский NSView, который является частью xix файла подкласса NSDocument, который оживает поведением по умолчанию метода NSDocumentController openDocument:. В этом подклассе NSView я реализовал методы awakeFromNib, в которых вызывается метод NSWindow setAcceptsMouseMovedEvents:YES, и acceptsFirstMouse:, который возвращает YES. Но моя реализация метода mouseMoved: моего подкласса NSView не вызывается, когда я наводил на нее указатель мыши. В чем может быть проблема?
MouseMoved не называется
Ответ 1
Я не использовал mouseMoved: в реальном проекте (я только немного поиграл с ним). Насколько я могу судить, mouseMoved: вызывается только тогда, когда ваше представление является первым ответчиком, а затем не только, когда мышь находится над вашим представлением, но всегда, когда движется мышь. Возможно, вам лучше использовать NSTrackingArea. Подробнее см. Cocoa Руководство по обработке событий.
Ответ 2
Обязательно запросите событие mouseMoved отправлено:
NSTrackingAreaOptions options = (NSTrackingActiveAlways | NSTrackingInVisibleRect |
NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved);
NSTrackingArea *area = [[NSTrackingArea alloc] initWithRect:[self bounds]
options:options
owner:self
userInfo:nil];
Ответ 3
Как отмечают другие, NSTrackingArea является хорошим решением, и подходящим местом для установки области отслеживания является NSView.updateTrackingAreas(). Нет необходимости устанавливать существующее свойство NSWindow setAcceptsMouseMovedEvents.
В Swift 3:
class CustomView : NSView {
var trackingArea : NSTrackingArea?
override func updateTrackingAreas() {
if trackingArea != nil {
self.removeTrackingArea(trackingArea!)
}
let options : NSTrackingAreaOptions =
[.activeWhenFirstResponder, .mouseMoved ]
trackingArea = NSTrackingArea(rect: self.bounds, options: options,
owner: self, userInfo: nil)
self.addTrackingArea(trackingArea!)
}
override func mouseMoved(with event: NSEvent) {
Swift.print("Mouse moved: \(event)")
}
}
Ответ 4
Просто запустите кого-нибудь в этом. Я столкнулся с проблемой, когда я подклассифицировал подкласс и пытался добавить зону отслеживания в оба класса (по двум причинам).
Если вы делаете что-то вроде этого, вам нужно убедиться, что ваш вызов mouseMoved: и т.д. в супер или только один из ваших подклассов получит сообщение.
- (void) mouseMoved: (NSEvent*) theEvent
{
// Call the super event
[super mouseMoved: theEvent];
}