我有一个里面有几个NSView的NSCollectionView。NSView中有一个NSBox,当它被选中时,它会改变颜色。我还想让NSBox在悬停时改变颜色。
我继承了NSBox并添加了mouseEntered和mouseExited方法。我在viewWillMoveToWindow中使用了addTrackingRect,但问题是,只有当我首先选择框所在的子视图时,才会出现悬停效果。
此外,只有选中的方框才会发生悬停效果。我如何实现悬停效果,以便我的NSCollectionView中的所有NSView都立即显示该效果?
发布于 2016-03-07 12:42:42
您可以在NSView的子类中覆盖updateTrackingAreas来实现此行为:
接口
@interface HoverView : NSView
@property (strong, nonatomic) NSColor *hoverColor;
@endImplementation
@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发布于 2020-12-10 15:19:23
Swift 5
var mouseInside : Bool = false { didSet {
needsDisplay = true
}}
@IBInspectable var hoverColor : NSColor = .controlAccentColor
var trackingArea : NSTrackingArea?
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
if mouseInside {
hoverColor.setFill()
bounds.fill()
}
}
override func updateTrackingAreas() {
super.updateTrackingAreas()
ensureTrackingArea()
if let trackingArea = trackingArea, !trackingAreas.contains(trackingArea) {
addTrackingArea(trackingArea)
}
}
func ensureTrackingArea() {
if trackingArea == nil {
trackingArea = NSTrackingArea(rect: .zero,
options: [
.inVisibleRect,
.activeAlways,
.mouseEnteredAndExited],
owner: self,
userInfo: nil)
}
}
override func mouseEntered(with event: NSEvent) {
mouseInside = true
}
override func mouseExited(with event: NSEvent) {
mouseInside = false
}
}https://stackoverflow.com/questions/14635933
复制相似问题