【问题标题】:NSView mouseMoved event sometimes doesn't fireNSView mouseMoved 事件有时不会触发
【发布时间】:2014-11-20 06:46:24
【问题描述】:

我有一个视频播放应用程序,其中显示了一个 NSView,跟踪到鼠标坐标,以显示用户悬停在某个区域上时的时间位置。

这在 70% 的时间里都能完美运行,但它经常根本不触发。最有可能发生这种情况的时间似乎是第一次将鼠标带入视图内以及将鼠标悬停在该区域之外然后再次回到内部。

NSView子类里面的代码如下:

- (void)viewDidMoveToWindow
{
    if ([self window]) {
        [self resetTrackingRect];
    }
}

- (void)clearTrackingRect
{
    if (rolloverTrackingRectTag > 0)
    {
        [self removeTrackingRect:rolloverTrackingRectTag];
        rolloverTrackingRectTag = 0;
    }
}

- (void)resetTrackingRect
{
    [self clearTrackingRect];
    rolloverTrackingRectTag = [self addTrackingRect:[self visibleRect]
                                          owner:self userData:NULL assumeInside:NO];
}

- (void)resetCursorRects
{
    [super resetCursorRects];
    [self resetTrackingRect];
}

- (void)mouseEntered:(NSEvent *)theEvent
{
    // Only ask for mouse move events when inside rect because they are expensive
    [[self window] setAcceptsMouseMovedEvents:YES];
    [[self window] makeFirstResponder:self];

    // Tells the observer to show the time view
    [[NSNotificationCenter defaultCenter] postNotificationName:@"MWTimelineHover" object:self userInfo:[NSDictionary dictionaryWithObjectsAndKeys:theEvent,@"event",nil]];
}

- (void)mouseExited:(NSEvent *)theEvent
{
    [[self window] setAcceptsMouseMovedEvents:NO];
    [[self window] resignFirstResponder];

    // Tells the observer to hide the time view
    [[NSNotificationCenter defaultCenter] postNotificationName:@"MWTimelineHoverLeave" object:self];
}

- (void)mouseMoved:(NSEvent *)theEvent
{
    [super mouseMoved:theEvent];

    // Tells the observer to show the time view
    [[NSNotificationCenter defaultCenter] postNotificationName:@"MWTimelineHover" object:self userInfo:[NSDictionary dictionaryWithObjectsAndKeys:theEvent,@"event",nil]];
}

注意:在停止的情况下,不会调用 mouseExited 并且视图没有丢失 firstResponder 状态。我也没有拖动鼠标,只是正常移动它。

【问题讨论】:

    标签: objective-c cocoa


    【解决方案1】:

    您需要使用 NSTrackingArea。这是参考NSTrackingArea Class Reference

    - (void)commonInit {
        CGRect rect = CGRectMake(0.0f, 0.0f, self.frame.size.width, self.frame.size.height);
        NSTrackingAreaOptions options = NSTrackingActiveInKeyWindow | NSTrackingMouseMoved | NSTrackingInVisibleRect;
        _trackingArea = [[NSTrackingArea alloc] initWithRect:rect options:options owner:self userInfo:nil];
        [self addTrackingArea:_trackingArea];
    }
    

    希望对你有帮助。

    【讨论】:

    • 谢谢,但不幸的是这是同一个问题。如果我缓慢移动鼠标,我可以让它工作,但如果我快速移动它,它会停止,直到我将它停在该区域内,然后再次开始缓慢移动。
    • @mwoods:答案是正确的,不幸的是,NSTrackingAreaOptions 不适合您的情况。
    猜你喜欢
    • 1970-01-01
    • 2017-02-06
    • 2014-12-06
    • 1970-01-01
    • 2014-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多