Cocoa button rollovers with mouseEntered: and mouseExited:?

While setting up a tracking area is definitely a way to do this, NSButton/NSButtonCell already have this functionality built in.

Check out NSButton's showsBorderOnlyWhileMouseInside, and the corresponding NSButtonCell's mouseEntered and mouseExited. It is documented here:

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

Depending on your use-case, this may or may not work. For me, I was subclassing NSButtonCell anyways, so it was perfect. One thing to be aware of is it also affects calls to drawBezel.


The problem is that NSButton can handle some mouse events only if you add your custom NSTrackingArea to button.

Try to add this code in your button class. It helped me. Also you can play with options if they not satisfied you.

- (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];
}

Hope it helps.