2013-03-02 66 views
7

我想創建一個自定義NSWindow,所以我創建了一個具有適當的無邊界窗口掩碼和工程。我提供了我自己的內容視圖,這很好。但我想要做的是繪製圓角,剪輯子視圖到這些角落。這可能嗎?自定義NSWindow與剪輯子視圖的圓角

在我的內容視圖中,我可以覆蓋drawRect:並繪製具有圓角的路徑,但是當我爲此添加子視圖時,它們不會被裁剪。

我可以改爲將我的內容視圖分層並將其設置爲圓角半徑(masksToBounds設置爲YES),但是當我添加子視圖時,它們仍然未被我的圓角裁剪。

有沒有辦法做到這一點?或者有一種方法可以繪製一個沒有標題欄的NSWindow,並且我可以完全控制繪圖,但仍然保留圓角的裁剪邊角?

回答

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 

我結束了:

Rounded window with clipped subview

+0

其他讀者應該注意,OpenGL應用程序應該只對整個場景使用一個'glDrawArrays()'命令,否則該圖層會導致奇怪的結果。在這個問題的範圍中,對於OS X樣式角使用4.5-5.0的拐角半徑。如果你願意的話,你也可以保持正常的標題欄,而不會讓它看起來太不同。 – Justin 2013-03-03 02:48:54

+4

@ericgorr任何想法如何讓這個陰影? – 2013-06-21 06:26:49

5

什麼@ericgorr是建議是正確的。另外,如果你想在窗口可以移動和resizable變化NSWindow的初始化如下,

- (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 codehttp://developer.apple.com/library/mac/#samplecode/RoundTransparentWindow/Introduction/Intro.html

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];