22

I'd like the NSTextFields I set up in Interface Builder to have shadows. I've implemented a way to do this which seems to work, but I'm not sure if it's the right way.

What I did is subclass NSTextFieldCell as follows and then set my subclass as the NSTextField's cell's type in IB. Is there a problem with this approach? Is there a better way?

#import "ShadowTextFieldCell.h"

static NSShadow *kShadow = nil;

@implementation ShadowTextFieldCell

+ (void)initialize
{
    kShadow = [[NSShadow alloc] init];
    [kShadow setShadowColor:[NSColor colorWithCalibratedWhite:0.f alpha:0.08f]];
    [kShadow setShadowBlurRadius:0.f];
    [kShadow setShadowOffset:NSMakeSize(0.f, -2.f)];
}

- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
    [kShadow set];
    [super drawInteriorWithFrame:cellFrame inView:controlView];
}

@end
sam
  • 3,399
  • 4
  • 36
  • 51
  • 1
    That's exactly how you're supposed to do it. The fancier way is to put your shadow-field class in its own bundle with an IB plugin, and then IB can actually render the shadow for you during layout; but that's way overkill and IB plugins are (temporarily?) MIA in xcode 4 anyway. – rgeorge Jul 09 '11 at 02:04

3 Answers3

10

Rather than subclass, you can just use NSCell's setBackgroundStyle:

[[aTextField cell] setBackgroundStyle:NSBackgroundStyleRaised];

See this similar question;

Community
  • 1
  • 1
zpasternack
  • 17,838
  • 2
  • 63
  • 81
8

There's nothing wrong with this approach. The other option would be to layer-back your text field (call [textField setWantsLayer:YES] and use CALayer's shadow properties, but this is often an undesirable way to do it because Core Animation's text rendering lacks subpixel antialiasing.

indragie
  • 18,002
  • 16
  • 95
  • 164
1

Easiest way is

[[yourTextField cell] setBackgroundStyle:NSBackgroundStyleRaised]; 

just like zpasternack said, but this is used only for default shadow-ing, for custom one subclass or use the layer...

Catalin
  • 1,821
  • 4
  • 26
  • 32