NSCollectionView+NSScrollView 中的鼠标悬停

Posted

技术标签:

【中文标题】NSCollectionView+NSScrollView 中的鼠标悬停【英文标题】:Mouseovers in NSCollectionView+NSScrollView 【发布时间】:2013-07-18 18:30:50 【问题描述】:

在 10.7+ 项目中,当鼠标位于集合视图项的视图范围内时,我试图在 NSCollectionViewItem 中启用 UI 元素。对于填充 NSCollectionView 的每个集合视图项,我有一个自定义视图,它使用其边界创建一个单独的 NSTrackingArea:

- (void) initializeMouseTracking

    self.trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds] options:NSTrackingMouseEnteredAndExited|NSTrackingActiveAlways owner:self userInfo:nil];
    [self addTrackingArea:self.trackingArea];

    NSPoint mouseLocation = [[self window] mouseLocationOutsideOfEventStream];
    mouseLocation = [self convertPoint: mouseLocation fromView: nil];

    if (NSPointInRect(mouseLocation, [self bounds]) == YES)
    
        [self mouseEntered:nil];
    
    else
    
        [self mouseExited:nil];
    

在滚动 NSCollectionView 内容之前,跟踪区域工作得很好。很明显,在滚动期间和之后需要重置跟踪区域。 我尝试以多种方式使 NSTrackingAreas 无效并重新创建:

- (void) resetMouseTracking

    [self removeTrackingArea:self.trackingArea];
    [self initializeMouseTracking];



- (void) scrollWheel:(NSEvent *)theEvent

    [self resetMouseTracking];
    [super scrollWheel:theEvent];



- (void) viewDidMoveToWindow:(NSWindow *)newWindow
   
    [self resetMouseTracking];
    [super viewWillMoveToWindow:newWindow];



- (void) updateTrackingAreas

    [self resetMouseTracking];
    [super updateTrackingAreas];

但这些尝试不仅有不完整和错误的结果,而且在滚动期间不断重新计算跟踪区域(ala 滚轮:) 似乎没有必要。相反,有一种有效的方法来捕获滚动事件的开始和偏移(在 ios 中很容易做到),这样我就可以在滚动期间使所有跟踪区域无效。在滚动视图的 contentView 上使用 NSViewBoundsDidChangeNotification 告诉我滚动正在发生,但它不指示它何时开始或停止。

从 NSScrollView 获取滚动开始和结束通知需要深度子类化还是我忽略了其他东西?是否有一种完全不同的方法可以显示更多的希望?

【问题讨论】:

我决定使用不同的解决方案,在包含 NSCollectionView 的 NSScrollView 子类的边界上使用单个跟踪区域。在mouseMoved中:在查询集合视图及其原型视图并从NSClipView获取documentVisibleRect后,计算鼠标悬停在集合视图项的索引。然后,我通过集合视图项向适当的视图发送消息。剩下的唯一问题是集合视图项在滚动期间不会更新。但滚动完成后,将鼠标悬停在预期的作品上。 【参考方案1】:

在 Cocoa 中用于滚动视图,与 iOS 不同,所有操作都在 documentView 上完成(而不是 contentView)。 您可能需要 [scrollView documentVisibleRect].origin 作为内容偏移量。

查看answer 了解更多类似的 UIScrollView 和 NSScrollView 比较

【讨论】:

对不起,如果我的问题不清楚。我有兴趣了解滚动开始和停止的时间,而不是获取内容偏移量并将其与集合视图项进行协调。我编辑了我的问题以反映这一点。此外,NSTrackingArea 使用关联视图坐标中的 NSRect 初始化; NSTrackingArea 在内部处理被跟踪视图与其父视图的关系。手头的问题是时间问题,而不是地点问题。 我猜你可以为这个属性添加一个观察者。然后实现逻辑来检查最后一点。我猜这会节省你的子类化。【参考方案2】:

另一种方法... NSView 继承自 NSResponder 类。 NSResponder 有方法“mouseEntered:”和“mouseExited:”。我的建议是尽可能在你的 NSView 子类中使用它们并跳过跟踪区域。

【讨论】:

NSTrackingArea 实际上允许这两种方法触发,否则不会触发。我最初没有在我的问题中包含我覆盖的 mouseEntered: 和 mouseExited: 方法。

以上是关于NSCollectionView+NSScrollView 中的鼠标悬停的主要内容,如果未能解决你的问题,请参考以下文章

NSCollectionView 斯威夫特

带有网络图像的 NSCollectionView

GCD 块不更新 NSCollectionView

NSCollectionView+NSScrollView 中的鼠标悬停

NSCollectionView 中的居中项目

NSCollectionView 是不是与 CoreData 兼容