NSView或NSWindow中的孔

Gra*_*son 13 xcode cocoa objective-c

是否可以删除NSWindow或NSView的部分内容并让它们通过?我有一个带有NSView的NSWindow,我想要:

A)在NSWindow打个洞,以便能够透过它看到

B)设置我的NSWindow背景以获得清晰的颜色,然后在顶部创建一个NSView并设置我的NSViews不透明度的某一部分,以便能够看到桌面.

这是我想要创建的效果:

在此输入图像描述

spu*_*fle 23

是的,这是可能的,实际上并不那么难.

在窗口子类中,您需要将窗口背景颜色设置为透明

self.backgroundColor = NSColor.clearColor;
Run Code Online (Sandbox Code Playgroud)

告诉合成引擎窗口的某些部分是透明的,当窗口移动时需要重新绘制

[self setOpaque:NO];
Run Code Online (Sandbox Code Playgroud)

在早期版本的macOS中没有必要设置背景颜色,许多答案仍然没有提到这一事实.我已经验证了至少从macOS 10.11开始就有必要了.

在NSView子类中,必须使用您选择的颜色渲染新背景(否则窗口完全透明,只显示标题栏),然后在视图中渲染一个洞

NSRectFillUsingOperation(NSMakeRect(50, 50, 100, 100), NSCompositingOperationClear);
Run Code Online (Sandbox Code Playgroud)

这给出了期望的效果,也适用于莫哈韦的黑暗模式等.

在黑暗模式下有洞的窗口

完整代码:

@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
Run Code Online (Sandbox Code Playgroud)