3

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

4

2 回答 2

0

在 Cocoa 的滚动视图中,与 iOS 不同的是,一切都在documentView(而不是contentView)上完成。您可能需要[scrollView documentVisibleRect].origin内容偏移量。

查看此答案以获取 UIScrollView 和 NSScrollView 的更多类似比较

于 2013-07-18T19:42:22.347 回答
-1

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

于 2013-07-18T18:51:23.967 回答