3

I am trying to get a inner shadow on a label in my Mac app.

I am trying to match the Photoshop design my designer sent over. The look I am trying to match is: Photoshop Design

The way this is being done in Photoshop is by setting an inner shadow with the following settings: Photoshop Settings

I have seen several different solutions for this type of thing here on other sites, but none of them work right.

For example everyone says to use:

[[myNSTextField cell] setBackgroundStyle:NSBackgroundStyleRaised];

I have found lots of stuff about doing an inner shadow on a NSBezierPath or similar but not with a label.

This answer to a question says to use the above setBackgroundStyle and then says to

Your gradient background then could be reached for example by using a custom view with a NSGradient

But where does this view go? The link the answer references talks about doing a inner shadow on a window again, not text.

Can anyone help me out with this?

Thanks

kdbdallas
  • 4,513
  • 10
  • 38
  • 53

2 Answers2

4

This effect is very easy to make in Photoshop. Unfortunately, in Cocoa applications it is not so straight forward. I do not know an easy way to do it with standard controls, but I will tell you how I would deal with the problem.

The problem is that a shadow must be dropped by and object. In other words, the shadow is always modal, one cannot just draw a shadow without actual object. In core graphics the shadow is a property of the drawing context. When we render an object we can add the shadow effect to the process.

Now, when we know the real problem, the solution is a piece of cake :)

Let's say here is the image generated from your text. You can find examples in the internet how to render text to a bitmap context.

enter image description here

You need only to:

Invert it.

enter image description here

Render it with the shadow down to an image (bitmap context).

enter image description here

Mask the image by excluding the inverted image.

enter image description here

Render the result image on the background texture you have.

enter image description here

I would make an NSView subclass and draw all this stuff on the layer. You can find examples of how to make you own bitmap context and draw on it. Here is how to work with masks https://developer.apple.com/library/mac/#documentation/graphicsimaging/conceptual/drawingwithquartz2d/dq_images/dq_images.html

I hope this helps.

Davyd Geyl
  • 4,578
  • 1
  • 28
  • 35
1

I was unable to figure out a way to do a shadow on the text of an NSTextField. It may be possible, but it is pretty easy for an NSTextView which for a simple label should be a reasonable alternative.

Here is an example for a label with a clear background and white text with a small black shadow on the text.

NSTextView *textView = [[NSTextView alloc] initWithFrame:NSMakeRect(10.0, 10.0f, 200.0f, 20.0f)];
[textView setSelectable:FALSE];
[textView setTextColor:[NSColor whiteColor]];
[textView setBackgroundColor:[NSColor clearColor]];
[textView setFont:[NSFont systemFontOfSize:14.0f]];
[textView setString:@"Boom goes the dynamite!"];

NSShadow *shadow = [[NSShadow alloc] init];
[shadow setShadowColor:[NSColor blackColor]];
[shadow setShadowOffset:NSMakeSize(1.0f, 1.0f)];
[shadow setShadowBlurRadius:1.0];
[textView setShadow:shadow];

[parentView addSubview:textView];

Which gives the following:

NSTextView text shadow example

InfalibleCoinage
  • 588
  • 13
  • 21