NSTableCellView无法获得第一个焦点

时间:2016-06-09 16:52:52

标签: objective-c swift macos cocoa

我真的试图解决这个特殊问题。已经很久了。

我有一个Mac应用程序,它完全位于状态栏中。每当我通过单击状态栏图标打开应用程序时,弹出窗口将打开contentViewControllercontentViewController有一个tableView和多个tableView个单元格,它们是NSTableCellView的子类。单元格有一个按钮,我使用mouseEntered子类中的mouseExitedNSTableViewCell事件隐藏和取消隐藏。每当我点击单元格时,它就会将我带到网络,就像在默认Web浏览器中打开URL一样,也会关闭popOver。当跟踪事件pointingHandCursor被调用时,会激活mouseEntered。在arrowCursor子类

中调用跟踪事件mouseExited时,它也会更改为默认NSTableCellView

好。每当我打开应用程序时,它都会正确显示pointingHandCursor因为事件被调用并且光标被更改了。现在我点击了单元格,在Web浏览器中打开了链接,popOver关闭了。现在,再次单击状态栏图标打开应用程序。现在最糟糕的事情发生了,我可以在tableView中滚动鼠标但同时我可以看到光标没有变为pointingHandCursor。

我尝试过调用acceptFirstMouse个事件和becomeFirstResponder。无处不在,在contentViewControllers视图的子类中,在NSTableCellView的子类中,在视图窗口中...基本上无处不在。这对我没有帮助。

此外,我尝试添加global mouse monitor并听取mouseMoved事件,在此事件中,我尝试在becomeFirstResponder视图中设置acceptFirstMouseMovecontentViewControllers,没有工作。

然后我尝试在NSTableCellView的子类中再次调用相同的监视器并执行相同的操作,但也没有工作。

基本上没有一个给我预期的行为。我想实现这个目标。

请帮帮我。如果你想要一个如何工作的例子。按照这个,

下载产品搜索应用程序,打开它,点击任何帖子,它会在网络浏览器中加载帖子,回来,打开应用程序,滚动,你可以看到pointingHandCursor。但在我打开网址后,pointing HandCursor没有到来。 :(

1 个答案:

答案 0 :(得分:0)

Apple与NSTrackingArea有长期存在的错误。 您必须验证当前鼠标位置是否仍然有效。

使用它:

NSPoint cursorPt = [self convertPoint:[[self window] mouseLocationOutsideOfEventStream] fromView:NULL];

不是这个:

[self convertPointFromBase:[ev locationInWindow]];

我在鼠标跟踪UI中使用类似以下的代码。

- (void)resetCursorRects
{
    [self adjustTrackingArea];
}

- (void) adjustTrackingArea
{
    if ( trackingArea )
    {
        [self removeTrackingArea:trackingArea];
        [trackingArea release];
    }

    // determine the tracking options
    NSTrackingAreaOptions trackingOptions = NSTrackingEnabledDuringMouseDrag | NSTrackingMouseMoved |
    NSTrackingMouseEnteredAndExited |
    //NSTrackingActiveInActiveApp | NSTrackingActiveInKeyWindow | NSTrackingActiveWhenFirstResponder |
    NSTrackingActiveAlways | NSTrackingAssumeInside | NSTrackingInVisibleRect;
    NSRect theRect = [self visibleRect];
    trackingArea = [[NSTrackingArea alloc]
                    initWithRect: theRect
                    options: trackingOptions
                    owner: self
                    userInfo: nil];
    [self addTrackingArea:trackingArea];

    //  DOESN'T work on any OS version up to 10.10 self addToolTipRect:r  owner:self userData:nil];

    [controller mouseMoved:[NSApp currentEvent]]; // tracking area changes imply mouseMoved in its scroll view (virtually)
    // IMHO a bug that apple doesn't call mouseMoved here.
}

- (void) mouseDown:(NSEvent*)evt { [controller mouseDown:evt]; }
- (void)mouseMoved:(NSEvent *)theEvent
{
    [controller mouseMoved:theEvent];
    if ( [theEvent type] == NSMouseMoved )
        [super mouseMoved:theEvent];
}

- (void)mouseEntered:(NSEvent *)theEvent
{
    // make sure current mouse cursor location remains under the mouse cursor
    NSPoint cursorPt = [self convertPoint:[[self window] mouseLocationOutsideOfEventStream] fromView:NULL];

    // apple bug!!!
    //NSPoint cursorPt2 = [self convertPointFromBase:[ev locationInWindow]];
    //if ( cursorPt.x != cursorPt2.x )
    //   NSLog( @"hello old cursorPt" );
    NSRect r = [self frame];
    if ( cursorPt.x > NSMaxX( r ) || cursorPt.x < 0 )
    {
        [self mouseExited:theEvent];
        return;
    }

    [self mouseMoved:(NSEvent *)theEvent];
    [super mouseEntered:theEvent];
}

- (void)mouseExited:(NSEvent *)theEvent
{
    if ( controller.mouseHoverKey )
    {
        controller.mouseHoverKey = nil;
        [self setNeedsDisplay:YES];
    }
    //    if ( mouseHoverRow >= 0 && mouseHoverRow < [self numberOfRows] )
    //        [self setNeedsDisplayInRect:[self rectOfRow:mouseHoverRow]];
    //    mouseHoverRow = mouseHoverColumn = -1;
    //if ( [[self delegate] conformsToProtocol:@protocol(MouseHoverProtocol)] )
    //    [(id<MouseHoverProtocol>)[self delegate] resetMouseHoverInfo:self];
    //if ( [theEvent type] == NSMouseExited )
    //    [[NSCursor arrowCursor] set];
    [super mouseExited: theEvent];
}