I have an NSCollectionView
with a few NSView
s in it. The NSView
has an NSBox
in it that changes color when it is selected. I want to also make the NSBox
change color when hovered over.
I subclassed NSBox
and added the mouseEntered
and mouseExited
methods. I used addTrackingRect
inside of viewWillMoveToWindow
but the problem is that the hover over effect only happens if I first select the subview that the box is in.
Furthermore only the box that is selected has the Hover Over effect happening on it. How can I implement the Hover Over effect such that all the NSView
s in my NSCollectionView
show the effect immediately?
You can override updateTrackingAreas
in a subclass of NSView
to accomplish this behavior:
Interface
@interface HoverView : NSView
@property (strong, nonatomic) NSColor *hoverColor;
@end
Implementation
@interface HoverView ()
@property (strong, nonatomic) NSTrackingArea *trackingArea;
@property (assign, nonatomic) BOOL mouseInside;
@end
@implementation HoverView
- (void) drawRect:(NSRect)dirtyRect {
[super drawRect:dirtyRect];
// Draw a white/alpha gradient
if (self.mouseInside) {
[_hoverColor set];
NSRectFill(self.bounds);
}
}
- (void) updateTrackingAreas {
[super updateTrackingAreas];
[self ensureTrackingArea];
if (![[self trackingAreas] containsObject:_trackingArea]) {
[self addTrackingArea:_trackingArea];
}
}
- (void) ensureTrackingArea {
if (_trackingArea == nil) {
self.trackingArea = [[NSTrackingArea alloc] initWithRect:NSZeroRect
options:NSTrackingInVisibleRect | NSTrackingActiveAlways | NSTrackingMouseEnteredAndExited
owner:self
userInfo:nil];
}
}
- (void) mouseEntered:(NSEvent *)theEvent {
self.mouseInside = YES;
}
- (void) mouseExited:(NSEvent *)theEvent {
self.mouseInside = NO;
}
- (void) setMouseInside:(BOOL)value {
if (_mouseInside != value) {
_mouseInside = value;
[self setNeedsDisplay:YES];
}
}
@end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With