我真的试图解决这个特殊问题。已经很久了。
我有一个Mac应用程序,它完全位于状态栏中。每当我通过单击状态栏图标打开应用程序时,弹出窗口将打开contentViewController
。 contentViewController
有一个tableView
和多个tableView
个单元格,它们是NSTableCellView
的子类。单元格有一个按钮,我使用mouseEntered
子类中的mouseExited
和NSTableViewCell
事件隐藏和取消隐藏。每当我点击单元格时,它就会将我带到网络,就像在默认Web浏览器中打开URL
一样,也会关闭popOver
。当跟踪事件pointingHandCursor
被调用时,会激活mouseEntered
。在arrowCursor
子类
mouseExited
时,它也会更改为默认NSTableCellView
好。每当我打开应用程序时,它都会正确显示pointingHandCursor
因为事件被调用并且光标被更改了。现在我点击了单元格,在Web浏览器中打开了链接,popOver关闭了。现在,再次单击状态栏图标打开应用程序。现在最糟糕的事情发生了,我可以在tableView中滚动鼠标但同时我可以看到光标没有变为pointingHandCursor。
我尝试过调用acceptFirstMouse
个事件和becomeFirstResponder
。无处不在,在contentViewControllers
视图的子类中,在NSTableCellView
的子类中,在视图窗口中...基本上无处不在。这对我没有帮助。
此外,我尝试添加global mouse monitor
并听取mouseMoved
事件,在此事件中,我尝试在becomeFirstResponder
视图中设置acceptFirstMouseMove
和contentViewControllers
,没有工作。
然后我尝试在NSTableCellView
的子类中再次调用相同的监视器并执行相同的操作,但也没有工作。
基本上没有一个给我预期的行为。我想实现这个目标。
请帮帮我。如果你想要一个如何工作的例子。按照这个,
下载产品搜索应用程序,打开它,点击任何帖子,它会在网络浏览器中加载帖子,回来,打开应用程序,滚动,你可以看到pointingHandCursor
。但在我打开网址后,pointing HandCursor
没有到来。 :(
答案 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];
}