【问题标题】:Hover Over effect in NSCollectionViewNSCollectionView 中的悬停效果
【发布时间】:2013-01-16 03:41:06
【问题描述】:
我有一个NSCollectionView,里面有几个NSViews。 NSView 中有一个NSBox,当它被选中时会改变颜色。我还想让NSBox 在悬停时改变颜色。
我继承了NSBox 并添加了mouseEntered 和mouseExited 方法。我在viewWillMoveToWindow 中使用了addTrackingRect,但问题是只有在我首先选择框所在的子视图时才会出现悬停效果。
此外,只有被选中的框才会发生悬停效果。如何实现悬停效果,使我的NSCollectionView 中的所有NSViews 立即显示效果?
【问题讨论】:
标签:
objective-c
xcode
cocoa
nsview
nscollectionview
【解决方案1】:
您可以在NSView 的子类中覆盖updateTrackingAreas 来完成此行为:
界面
@interface HoverView : NSView
@property (strong, nonatomic) NSColor *hoverColor;
@end
实施
@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
【解决方案2】:
斯威夫特 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
}
}