Customizing your application’s Dock icon with a smooth animation, in two easy steps.
If you are simply replacing your application’s icon, then things are pretty easy: load (or generate) your animation frames as CGImageRefs
, and use
SetApplicationDockTileImage
.
However, if you are trying to composite the animation frames on top of your existing application icon, it gets a little more interesting.
BeginCGContextForApplicationDockTile
does nothing to restore your original application icon, so if you try to draw two frames in succession using
BeginCGContextForApplicationDockTile
, you’ll end up with both of them on top of you application icon, which is probably not what you wanted.
OverlayApplicationDockTileImage
has exactly the same problem — if you call it twice in a row, it overlays both images on top of your application icon.
RestoreApplicationDockTileImage
is supposed to help with this problem, but, unfortunately, if forces the original application icon to be drawn in the Dock
immediately, before you’ve had a chance to composite your next animation frame. This results in unsightly flicker.
Clearly, every time you advance to a new frame, you need to draw the application icon and then composite the appropriate animation frame, without flushing the application icon without the animation frame first. For example:
// Dock icons are 128x128
CGRect iconRect = CGRectMake(0, 0, 128, 128);
CGContextRef context = BeginCGContextForApplicationDockTile();
// Erase whatever may be in the dock icon now
CGContextClearRect(context, iconRect);
// Draw the app icon first
PlotIconRefInContext(
context,
&iconRect,
kAlignNone,
kTransformNone,
NULL,
kPlotIconRefNormalFlags,
appIconRef
);
// Draw your animation here
CGContextFlush(context);
EndCGContextForApplicationDockTile(context);
You can get your application icon with:
// Get a CFURL for the appname.icns file
CFURLRef icnsURL = CFBundleCopyResourceURL(GetMainBundle(), CFSTR("appname"), CFSTR("icns"), NULL);
// Get the FSRef for the icns file
FSRef icnsRef;
CFURLGetFSRef(icnsURL, &icnsRef);
// Get the icon from the icns file
IconRef appIcon;
GetIconRefFromFile(icnsRef, &appIcon, NULL);