我正在尝试创建一个自定义NSWindow
,因此我创建了一个具有正确的无边框窗口掩码并且可以正常工作。我提供自己的内容视图很好。但我要做的是绘制圆角,也将子视图剪辑到那些角落。这可能吗?
在我的内容视图中,我可以覆盖drawRect:
并绘制带圆角的路径,但是当我向其添加子视图时,它们不会被剪裁。
我可以改为使我的内容视图支持图层并为其设置一个角半径(masksToBounds
设置为YES
)但是当我添加子视图时,它们仍然没有被我的圆角修剪
有办法做到这一点吗?或者某种方式来绘制一个没有标题栏的NSWindow,我可以完全控制绘图,并保持圆角的剪裁角落?
答案 0 :(得分:12)
我能做的是提供我的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
我最终得到了:
答案 1 :(得分: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 sample code http://developer.apple.com/library/mac/#samplecode/RoundTransparentWindow/Introduction/Intro.html
答案 2 :(得分: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];