我正在尝试创建一个允许在ShieldingWindowLevel绘图的叠加窗口,但是当窗口出现时,光标仍然是默认指针。我想把它换成十字准线。在我感到困惑之前有控制器NSCursors,为什么resetCursorRects没有被调用。
我手动创建窗口如下(在我的AppController类中):
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Create the window
NSRect frame = [[NSScreen mainScreen] frame];
// Provide a small area on the right to move the cursor in-and-out of the window.
frame.size.width = frame.size.width - 20;
self.window = [[NSWindow alloc] initWithContentRect:frame
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:NO];
[self.window setAcceptsMouseMovedEvents:YES];
[self.window setOpaque:NO];
[self.window setLevel:CGShieldingWindowLevel()];
[self.window setBackgroundColor:[NSColor colorWithDeviceRed:0.0 green:0.0 blue:1.0 alpha:0.2]];
// Create the subview
ScreenOverlayView *subview = [[ScreenOverlayView alloc] initWithFrame:NSZeroRect];
[[self.window contentView] addSubview:subview];
// Add subview and show window
[self.window setContentView:subview];
[self.window makeFirstResponder:subview];
[self.window orderFrontRegardless];
}
使用以下NSView子类:
@implementation ScreenOverlayView
- (void) resetCursorRects {
[super resetCursorRects];
[self addCursorRect: [self bounds]
cursor: [NSCursor crosshairCursor]];
}
// ...
@end
我创建了一个示例项目来展示此案例并将其发布到github,最有趣的文件是ScreenOverlayView.m和AppDelegate.m。
我应该指出,我也花了很多时间尝试使用NSTrackingArea,正如您在示例项目中看到的那样。如果鼠标在出现后进入视图,则跟踪区域可以正常工作,但如果鼠标在内部开始,则无法进入。如果我有一些设置初始光标的方法,使用MouseEnter和MouseLeave会很好,但它只会在改变之前一瞬间改变。
如何调用resetCursorRects -OR-当我将光标移动到superview时如何设置光标?
答案 0 :(得分:3)
关键是你真的需要创建一个NSWindow
的自定义子类,以抵消无边界窗口(NSBorderlessWindowMask
)的一些默认行为。
示例项目的更新版本位于http://www.markdouma.com/developer/full-screen-overlay.zip。
在其中,我创建了一个自定义的MDScreenOverlayWindow
类,它覆盖了NSWindow的canBecomeKeyWindow
方法,如下所示:
// Windows created with NSBorderlessWindowMask normally can't be key,
but we want ours to be
- (BOOL)canBecomeKeyWindow {
return YES;
}
这将使您的视图成为关键,基本上所有其他内容都能正常工作。
可能值得注意的另一件事是drawRect:
方法。 (看起来你可能来自iOS)。您可能希望查看NSBezierPath
,因为它可能会简化您的一些绘图代码。例如,我相信您的绘图代码可以合并到以下内容中:
- (void)drawRect:(NSRect)rect {
// the color should probably be "pre-multiplied" by the alpha
// premultiplied version:
[[NSColor colorWithCalibratedRed:0.8 green:0.0 blue:0.0 alpha:0.8] set];
[NSBezierPath setDefaultLineWidth:2.0];
[NSBezierPath strokeLineFromPoint:currentLocation toPoint:downLocation];
}