Is there any way to draw an NSImage like images in NSButtons or other cocoa interface elements?
Here are examples:
Apple uses pdf's with black icons:
Is there any way to draw an NSImage like images in NSButtons or other cocoa interface elements?
Here are examples:
Apple uses pdf's with black icons:
To get to draw correctly within any rect, the
CGContextDrawImage
andCGContextFillRect
for the inner mask must have the origin of(0,0)
. then when you draw the image for the inner shadow you can then reuse the mask rect. So ends up looking like:You also have to leave a 1px border around the outside of the image or the shadows won't work correctly.
If you don't mind calling a private API, you can let the operating system (CoreUI) do the shading for you. You need a few declarations:
And for the actual drawing:
This will take the alpha channel of cgimage and apply the embossing effect as seen on toolbar buttons. You may or may not need the "is.flipped" line. Remove it if your result is upside-down.
There are a bunch of variations:
kCUIPresentationStateKey = kCUIPresentationStateInactive
: The window is not active, the image will be lighter.state = rollover
: Only makes sense with the previous option. This means you are hovering over the image, the window is inactive, but the button is sensitive (click-through is enabled). It will become darker.state = pressed
: Occurs when the button is pressed. The icon gets slightly darker.Bonus tip: To find out stuff like this, you can use the SIMBL plugin CUITrace. It prints out all the CoreUI invocations of a target app. This is a treasure trove if you have to draw your own native-looking UI.
Here's a much simpler solution: just create a cell and let it draw. No mucking around with private APIs or Core Graphics.
Code could look similar to the following:
You can use different cells and configurations depending on the look you want to have (eg.
NSImageCell
withNSBackgroundStyleDark
if you want the inverted look in a selected table view row)And as a bonus, it will automatically look correct on all versions of OS X.
If you simply want this effect to be applied when you use your own images in a button, use
[myImage setTemplate:YES]
. There is no built-in way to draw images with this effect outside of a button that has the style shown in your screenshots.You can however replicate the effect using Core Graphics. If you look closely, the effect consists of a horizontal gradient, a white drop shadow and a dark inner shadow (the latter is the most difficult).
You could implement this as a category on
NSImage
:Example usage in a view:
This would give you the following result (shown in different sizes):
You may need to experiment a bit with the gradient colors and offset/blur radius of the two shadows to get closer to the original effect.