Ролловеры кнопки какао с помощью мыши Entered: и mouseExited:?

В надежде создать эффект прокрутки для кнопки, я создал подкласс NSButton под названием Button.

button.h:

#import <AppKit/AppKit.h>

@interface Button : NSButton {
}

- (void)mouseEntered:(NSEvent *)theEvent;
- (void)mouseExited:(NSEvent *)theEvent;
- (void)mouseDown:(NSEvent *)ev;
- (void)mouseUp:(NSEvent *)theEvent;

@end

Button.m: #import "Button.h"

@implementation Button

- (id)initWithFrame:(NSRect)frameRect  {
    self = [super initWithFrame:frameRect];
    if(self != nil) {
    NSLog(@"btn init");
}
    return self;
}


- (void)mouseEntered:(NSEvent *)theEvent{
    NSLog(@"mouseEntered");
    [self setImage:[NSImage imageNamed:@"lockIcon_2.png"]];
    [self setNeedsDisplay];
}
- (void)mouseExited:(NSEvent *)theEvent{
    [self setImage:[NSImage imageNamed:@"lockIcon_1.png"]];
    NSLog(@"mouseExited");  
    [self setNeedsDisplay];
}

- (void)mouseDown:(NSEvent *)ev {
    NSLog(@"mouseDown!");
}

- (void)mouseUp:(NSEvent *)ev {
    NSLog(@"mouseUp!");
}

@end

С кодом выше, каждый раз, когда я нажимаю на кнопку, я вижу "mouseDown" в журналах, но я не вижу ни "mouseEntered", ни "mouseExited" (и, конечно, не вижу изменения изображения)?? К сожалению, я знаю, что упускаю что-то очевидное, но я просто не вижу этого...???

1 ответ

Решение

Проблема в том, что NSButton может обрабатывать некоторые события мыши только в том случае, если вы добавите свою пользовательскую NSTrackingArea в кнопку.

Попробуйте добавить этот код в свой класс кнопок. Это помогло мне. Также вы можете играть с опциями, если они вас не устраивают.

- (void)createTrackingArea
{
    NSTrackingAreaOptions focusTrackingAreaOptions = NSTrackingActiveInActiveApp;
    focusTrackingAreaOptions |= NSTrackingMouseEnteredAndExited;
    focusTrackingAreaOptions |= NSTrackingAssumeInside;
    focusTrackingAreaOptions |= NSTrackingInVisibleRect;

    NSTrackingArea *focusTrackingArea = [[NSTrackingArea alloc] initWithRect:NSZeroRect
            options:focusTrackingAreaOptions owner:self userInfo:nil];
    [self addTrackingArea:focusTrackingArea];
}


- (void)awakeFromNib
{
    [self createTrackingArea];
}

Надеюсь, поможет.

Хотя настройка области отслеживания - определенно способ сделать это, NSButton/NSButtonCell эта функция уже встроена.

Проверьте NSButton's showsBorderOnlyWhileMouseInside, а соответствующие NSButtonCell mouseEntered а также mouseExited. Это описано здесь:

https://developer.apple.com/documentation/appkit/nsbuttoncell/1527903-showsborderonlywhilemouseinside

В зависимости от вашего варианта использования это может работать, а может и не работать. Для меня я все равно создавал подкласс NSButtonCell, так что это было идеально. Следует помнить, что это также влияет на вызовыdrawBezel.

Другие вопросы по тегам