CAShapeLayer または単に CALayer を使用して、NSWindow に「穴」を開けようとしています。
通常の NSViews またはレイヤーに基づくビューを使用する場合でも、次のようなコードを使用して drawRect: をオーバーライドできます。
[spotImage drawInRect:self.bounds fromRect:NSZeroRect operation:NSCompositeXOR fraction:1.0];
ここで、spotImage は純粋な白のコンテンツといくつかのグラデーションを含む NSImage であり、ウィンドウの背景は 0.5 アルファの黒です。この drawRect が定義されている NSView サブクラスには、clearColor の背景があります。
最終結果は灰色のウィンドウです (多くのサンプルで見られるように、NSBorderlessWindowMask の styleMask を持つ透明なウィンドウです。
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];