I'm working with a view-based NSTableView
that uses a custom cell view with several controls in it. One of the controls is an image-only NSButton
that either shows a checkmark image or no image at all. Additionally, when I mouse over one of these buttons that has no image, I would like a "faded" version of the checkmark image to be displayed while the mouse is inside the button.
I've gotten the code set up using NSTrackingArea to respond to -mouseEntered:
and -mouseExited:
events, calling -setImage:
on the NSButton to show the faded checkmark while the mouse is inside the button, then set the image back to nil when the mouse exits.
As far as I can tell, all that code seems to be working as expected, but while the button will update and show the checkmark image the first time the mouse enters the view, then disappear when it exits, moving the mouse back over the button a second time does not cause the button to redraw for some reason, leaving it always blank after the first redraw no matter how many times the image gets set.
This is a summary of the relevant code:
- (void)refreshActiveButton
{
self.activeButton.image = self.activeImage;
}
- (void)mouseEntered:(NSEvent *)theEvent
{
NSLog(@"mouse entered %@", self.listItem.name);
self.mouseOverActiveButton = YES;
[self refreshActiveButton];
}
- (void)mouseExited:(NSEvent *)theEvent
{
NSLog(@"mouse exited %@", self.listItem.name);
self.mouseOverActiveButton = NO;
[self refreshActiveButton];
}
- (NSImage*)activeImage
{
NSLog(@"returning new active image");
if (self.listItem.isActive)
return [NSImage imageNamed:@"checkmark16"];
else if (self.mouseOverActiveButton)
return fadedCheckmark;
else
return nil;
}
The button is set up in a .xib file as a "Momentary Push In" (I've also tried "Momentary Change" - same behavior) with no title displayed and no border.
Running in the debugger, I've been able to confirm that:
- The
-mouseEntered:
and-mouseExited:
methods do continue to get called when moving the mouse over the button, even when the display doesn't update. - The correct image is being assigned to the button, and is returned back from the button instance after being set. (either the fadedCheckmark image when the mouse is inside, or nil when the mouse is outside)
I tried calling -setNeedsDisplay:YES
on the button after assigning the image, as well as setting a layerContentRedrawPolicy
of NSViewLayerContentsRedrawOnSetNeedsDisplay
(the entire table view is layer-backed) with no change in behavior. Edit: also tried disabling layer backing altogether, with no change.
I feel like there must be something obvious staring me in the face that I'm missing, but if anyone can clue me in, I'd appreciate it.