IS it possible to cut out parts of a NSWindow or an NSView and make them see through? I have an NSWindow with an NSView and I want to either:
A) make a hole in the NSWindow to be able to see through it or
B) set my NSWindow background to have a clear color and then make an NSView on top and set a certain part of my NSViews opacity to be able to see through to the desktop.
This is the effect I am trying to create:
Yes, it's possible, and actually not that hard.
In your window subclass, you need to set the window background color to transparent
self.backgroundColor = NSColor.clearColor;
and tell the compositing engine that parts of your window are transparent and need to be redrawn when the window moves
[self setOpaque:NO];
Setting the background color was not necessary in early versions of macOS and many answers still do not mention that fact. I've verified that at least since macOS 10.11 it is necessary.
In your NSView subclass, you must render the new background with a color of your choice (otherwise the window is entirely transparent and only the title bar will show) and then render a hole in the view with
NSRectFillUsingOperation(NSMakeRect(50, 50, 100, 100), NSCompositingOperationClear);
This gives the desired effect and also works in Mojave's dark mode etc.
Full code:
@interface MyWindow : NSWindow
- (id)initWithContentRect:(NSRect)contentRect styleMask:( unsigned int)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag;
@end
@implementation MyWindow
- (id)initWithContentRect:(NSRect)contentRect styleMask:( unsigned int)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag {
self = [super initWithContentRect:contentRect styleMask : aStyle backing :bufferingType defer:flag ];
if (self)
{
self.backgroundColor = NSColor.clearColor;
[self setOpaque:NO];
[self setHasShadow:NO];
}
return self;
}
@end
@interface MyView : NSView
- (void)drawRect:(NSRect)rect;
@end
@implementation MyView
- (void)drawRect:(NSRect)rect
{
[[NSColor windowBackgroundColor] set];
NSRectFill(self.bounds);
NSRectFillUsingOperation(NSMakeRect(50, 50, 100, 100), NSCompositingOperationClear);
}
@end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With