我正在尝试使用 CAShapeLayer 甚至只是 CALayer 在 NSWindow 中制作一个“洞”。
当使用常规的 NSViews 甚至是支持层的视图时,我可以覆盖 drawRect: 使用如下代码:
[spotImage drawInRect:self.bounds fromRect:NSZeroRect operation:NSCompositeXOR fraction:1.0];
其中 spotImage 是一个具有纯白色内容和一些渐变的 NSImage,并且窗口具有黑色背景和 0.5 alpha。定义此 drawRect 的 NSView 子类具有 clearColor 背景。
最终结果是一个灰色窗口(它是一个透明窗口,其 styleMask 为 NSBorderlessWindowMask,可以在许多示例中找到。
如果我将 NSView 变成支持图层的视图,它会调用 drawRect 方法并且工作正常。
当我把它变成一个图层托管视图,并再次使用相同的结构(NSWindow > contentView > CustomView)时,drawInRect 方法只是绘制图像。它不再通过它打一个洞。
就像当它是层托管层次结构的一部分时,层本身不能再打洞。
这是一些示例代码:
自定义 NSWindow 子类初始化器:
- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag {
self = [super initWithContentRect:contentRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
if (self) {
[self setBackgroundColor: [NSColor lightGrayColor]]; //[NSColor clearColor]];
[self setAlphaValue:0.5];
[self setOpaque:NO];
[self setHasShadow: NO];
[self useOptimizedDrawing:YES];
[self setIgnoresMouseEvents:YES];
}
return self;
}
我的 applicationDidFinishLaunching 方法中的代码:
PPContentView *thisView = [[PPContentView alloc]
initWithFrame:CGRectInset([self.window.contentView bounds], 50, 50)];
//[thisView setWantsLayer:YES]; enabling this makes things opaque again
[self.window.contentView addSubview:thisView];
thisView.layer.backgroundColor = [NSColor clearColor].CGColor;
//Create custom content
[thisView setNeedsDisplay:YES];
}
我的自定义视图的 drawRect 包含:
[[NSImage imageNamed:@"spotFuzzy.png"] drawInRect:self.bounds fromRect:NSZeroRect operation:NSCompositeXOR fraction:1.0];