Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSWindow with round corners and shadow

I'm trying to crate a NSWindow without title bar (NSBorderlessWindowMask) with round corners and a shadow, similar to the below "Welcome to Xcode" window.

Welcome to Xcode

I make a subclass of NSWindow:

@implementation FlatWindow  - (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 setOpaque:NO];         [self setBackgroundColor:[NSColor clearColor]];         [self setMovableByWindowBackground:TRUE];         [self setStyleMask:NSBorderlessWindowMask];         [self setHasShadow:YES];     }      return self; }  - (void) setContentView:(NSView *)aView {     aView.wantsLayer            = YES;     aView.layer.frame           = aView.frame;     aView.layer.cornerRadius    = 10.0;     aView.layer.masksToBounds   = YES;      [super setContentView:aView]; }  @end 

And a subclass of NSView:

@implementation ColoredView  - (void)drawRect:(NSRect)dirtyRect {     [super drawRect:dirtyRect];      [[NSColor windowBackgroundColor] set];     NSRectFill(dirtyRect); }  @end 

This gives me a window without title bar with round corners, but the default shadow on NSWindow is gone. How can I add the default shadow to this window?

Flat window

EDIT1:

NSWindow with NSShadow. This shadow is not shown.

@implementation FlatWindow  - (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 setOpaque:NO];         [self setBackgroundColor:[NSColor clearColor]];         [self setMovableByWindowBackground:TRUE];         [self setStyleMask:NSBorderlessWindowMask];         [self setHasShadow:YES];     }      return self; }  - (void) setContentView:(NSView *)aView {     aView.wantsLayer            = YES;     aView.layer.frame           = aView.frame;     aView.layer.cornerRadius    = 10.0;     aView.layer.masksToBounds   = YES;      NSShadow *dropShadow = [[NSShadow alloc] init];     [dropShadow setShadowColor:[NSColor blackColor]];     [dropShadow setShadowBlurRadius:10.0];     [aView setShadow: dropShadow];      [super setContentView:aView]; }  @end 
like image 966
dhrm Avatar asked Nov 12 '13 21:11

dhrm


1 Answers

Update

I realised old approach was not able to create precise round corner. So I updated example to make precise round corner.

enter image description here

        window1.backgroundColor             =   NSColor.whiteColor()         window1.opaque                      =   false         window1.styleMask                   =   NSResizableWindowMask                                             |   NSTitledWindowMask                                             |   NSFullSizeContentViewWindowMask         window1.movableByWindowBackground   =   true         window1.titlebarAppearsTransparent  =   true         window1.titleVisibility             =   .Hidden         window1.showsToolbarButton          =   false         window1.standardWindowButton(NSWindowButton.FullScreenButton)?.hidden   =   true         window1.standardWindowButton(NSWindowButton.MiniaturizeButton)?.hidden  =   true         window1.standardWindowButton(NSWindowButton.CloseButton)?.hidden        =   true         window1.standardWindowButton(NSWindowButton.ZoomButton)?.hidden         =   true          window1.setFrame(CGRect(x: 400, y: 0, width: 400, height: 500), display: true)         window1.makeKeyAndOrderFront(self) 

Here's full working example.


Oudated

Special treatment is not required at least in OS X 10.10.

import Cocoa  class ExampleApplicationController: NSObject, NSApplicationDelegate {     class ExampleController {          let window1 =   NSWindow()         let view1   =   NSView()          init(){             window1.setFrame(CGRect(x: 400, y: 0, width: 400, height: 500), display: true)             window1.contentView                 =   view1              window1.backgroundColor             =   NSColor.clearColor()             window1.opaque                      =   false             window1.styleMask                   =   NSBorderlessWindowMask | NSResizableWindowMask             window1.movableByWindowBackground   =   true             window1.makeKeyAndOrderFront(self)              view1.wantsLayer                =   true             view1.layer!.cornerRadius       =   10             view1.layer!.backgroundColor    =   NSColor.whiteColor().CGColor              /// :ref:   http://stackoverflow.com/questions/19940019/nswindow-with-round-corners-and-shadow/27613308#21247949             window1.invalidateShadow()  //  This manual invalidation is REQUIRED because shadow generation is an expensive operation.         }     }      let example1    =   ExampleController() } 

You can download a working example from here.

like image 101
eonil Avatar answered Oct 09 '22 03:10

eonil