Да, это возможно, и на самом деле не так сложно.
В вашем подклассе окна необходимо установить прозрачный цвет фона окна
self.backgroundColor = NSColor.clearColor;
и сообщите механизму компоновки, что части вашего окна прозрачны и должны быть перерисованы при перемещении окна
[self setOpaque:NO];
В ранних версиях macOS установка цвета фона не требовалась, и во многих ответах этот факт не упоминается. Я проверял, что, по крайней мере, начиная с macOS 10.11, это необходимо.
В вашем подклассе NSView вы должны визуализировать новый фон с цветом по вашему выбору (в противном случае окно будет полностью прозрачным и будет отображаться только строка заголовка), а затем визуализировать дыру в представлении с помощью
NSRectFillUsingOperation(NSMakeRect(50, 50, 100, 100), NSCompositingOperationClear);
Это дает желаемый эффект, а также работает в темном режиме Мохаве и т. Д.
Полный код:
@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