我一直在研究这个问题几个小时,不知道出了什么问题。我想要一个按钮的自定义光标,它是NSTextView的子视图,我添加了一个跟踪区域,并在鼠标输入按钮时发送cursorUpdate消息。
每次鼠标进入跟踪区域时,都会调用cursorUpdate方法。但光标仍然是IBeamCursor。
有什么想法吗?
Apple Docs的参考:managing cursor-update event
- (void)cursorUpdate:(NSEvent *)event {
[[NSCursor arrowCursor] set];
}
- (void)myAddTrackingArea {
[self myRemoveTrackingArea];
NSTrackingAreaOptions trackingOptions = NSTrackingCursorUpdate | NSTrackingMouseEnteredAndExited | NSTrackingActiveInKeyWindow;
_trackingArea = [[NSTrackingArea alloc] initWithRect: [self bounds] options: trackingOptions owner: self userInfo: nil];
[self addTrackingArea: _trackingArea];
}
- (void)myRemoveTrackingArea {
if (_trackingArea)
{
[self removeTrackingArea: _trackingArea];
_trackingArea = nil;
}
}
答案 0 :(得分:4)
我遇到了同样的问题。
问题是,NSTextView
每次收到mouseMoved:
事件时都会更新其光标。该事件由NSTrackingArea
的自我更新NSTextView
触发,该NSTextView
始终跟踪NSScrollView
内updateTrackingAreas
的可见部分。所以我可以想到两种解决方案。
覆盖mouseMoved:
删除Cocoa提供的跟踪区域,并确保始终创建一个新的跟踪区域,而不是按钮。 (我不会这样做!)
覆盖- (void)mouseMoved:(NSEvent *)theEvent {
NSPoint windowPt = [theEvent locationInWindow];
NSPoint superViewPt = [[self superview]
convertPoint: windowPt fromView: nil];
if ([self hitTest: superViewPt] == self) {
[super mouseMoved:theEvent];
}
}
并确保当光标位于按钮上时它不会调用super。
{{1}}
答案 1 :(得分:0)
我刚刚通过谷歌搜索遇到了这个问题,所以我想我会发布我的解决方案。
按照文档to create an NSTrackingArea中的步骤操作。应该看起来像下面这样。将此代码放在子类的init方法中(也添加updateTrackingAreas
方法):
NSTrackingArea *trackingArea = [[NSTrackingArea alloc] initWithRect:self.bounds options:(NSTrackingMouseMoved | NSTrackingActiveInKeyWindow) owner:self userInfo:nil];
[self addTrackingArea:trackingArea];
self.trackingArea = trackingArea;
现在您需要将mouseMoved:
方法添加到子类:
- (void)mouseMoved:(NSEvent *)theEvent {
NSPoint point = [self convertPoint:theEvent.locationInWindow fromView:nil];
if (NSPointInRect(point, self.popUpButton.frame)) {
[[NSCursor arrowCursor] set];
} else {
[[NSCursor IBeamCursor] set];
}
}
注意:self.popUpButton
是按钮,它是NSTextView / NSTextField的子视图。
就是这样!结果不是太难 - 只需使用mouseMoved:
代替cursorUpdate:
。我花了几个小时来解决这个问题,希望有人可以使用它。
答案 2 :(得分:0)
我遇到了同样的问题,但是使用了一个简单的NSView
子类,该子类是窗口的contentView
的子类,并且没有驻留在NScrollView
内。
cursorUpdate
的{{1}}标志的文档听起来像您只需要处理进入跟踪区域rect的鼠标即可。但是,我必须手动检查鼠标的位置,因为当鼠标进入跟踪区域的矩形和离开跟踪矩形的时都会调用NSTrackingArea
方法。因此,如果cursorUpdate(event:)
实现仅设置光标而不检查其是否位于跟踪区域rect内,则在进入并离开 rect时都将对其进行设置。
cursorUpdate(event:)
的文档说明:
重写此方法以设置光标图像。默认值 如果使用游标矩形,则实现使用游标矩形 目前有效。如果不是,则调用super发送消息 响应者链上。
如果响应者实现了此方法,但决定不处理 特定事件,它应调用的超类实现 这种方法。
cursorUpdate(event:)