8

我正在尝试创建一个 custom NSWindow,所以我创建了一个具有适当的无边框窗口掩码并且可以正常工作。我提供了我自己的内容视图,这很好。但我想做的是用圆角绘制,也可以将子视图剪辑到这些角。这可能吗?

在我的内容视图中,我可以覆盖drawRect:并绘制圆角路径,但是当我向其中添加子视图时,它们不会被剪裁。

我可以改为让我的内容视图层支持并给它一个角半径(masksToBounds设置为YES)但是当我添加子视图时,它们仍然没有被我的圆角剪裁。

有没有办法做到这一点?或者以某种方式绘制没有标题栏的 NSWindow 并且我可以完全控制绘图,同时保持圆角的剪裁角?

4

3 回答 3

13

我能够做的是提供我的 NSWindow 的自定义子类:

@implementation ELGRoundWindow

- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag
{
    self = [super initWithContentRect:contentRect styleMask:NSBorderlessWindowMask backing:bufferingType defer:flag];

    if ( self )
    {
        [self setStyleMask:NSBorderlessWindowMask];
        [self setOpaque:NO];
        [self setBackgroundColor:[NSColor clearColor]];
    }

    return self;
}


- (void) setContentView:(NSView *)aView
{
    aView.wantsLayer            = YES;
    aView.layer.frame           = aView.frame;
    aView.layer.cornerRadius    = 20.0;
    aView.layer.masksToBounds   = YES;


    [super setContentView:aView];

}

@end

然后在 IB 中,我将内容视图的类更改为 ELGRoundView:

@implementation ELGRoundView

- (void)drawRect:(NSRect)dirtyRect
{
    [[NSColor colorWithCalibratedRed:0.0 green:0.5 blue:1 alpha:1] set];
    NSRectFill(dirtyRect);
}

@end

我在内容视图中放置了另一个方形子视图,其中包含以下内容:

@implementation ELGSquareView

- (void)drawRect:(NSRect)dirtyRect
{
    [[NSColor colorWithCalibratedRed:0.0 green:0 blue:1 alpha:1] set];
    NSRectFill(dirtyRect);
}

@end

我最终得到:

带有剪裁子视图的圆角窗口

于 2013-03-02T21:51:42.710 回答
5

@ericgorr 的建议是正确的。此外,如果您希望窗口可移动且可调整大小,请按如下方式更改 NSWindow 的 init,

- (id)initWithContentRect:(NSRect)contentRect
                 styleMask:(NSUInteger)aStyle
                   backing:(NSBackingStoreType)bufferingType
                     defer:(BOOL)flag
{
    self = [super initWithContentRect:contentRect
                            styleMask:aStyle
                              backing:bufferingType
                                defer:flag];
    if (self) {            
        [self setOpaque:NO];
        [self setBackgroundColor:[NSColor clearColor]];
        [self setMovableByWindowBackground:YES];
        [self setStyleMask:NSResizableWindowMask];
    }
    return self;
}

如需进一步定制,请参阅Apple 示例代码 http://developer.apple.com/library/mac/#samplecode/RoundTransparentWindow/Introduction/Intro.html

于 2013-06-21T06:44:41.860 回答
1

子类化是最灵活的方式。如果您不想子类化,请使用此代码。

// unfortunately the window can't be moved
// but this is just an alert type window, so i don't care
//
[window setOpaque:NO];
[window setBackgroundColor:[NSColor clearColor]];

NSView*  contentView = window.contentView;

contentView.wantsLayer = YES;
contentView.layer.backgroundColor = [NSColor windowBackgroundColor].CGColor;
contentView.layer.masksToBounds = YES;
contentView.layer.cornerRadius = 16.0;

[window makeKeyAndOrderFront:self];
[window center];
于 2016-04-25T17:11:36.443 回答