Matt Gemmell

TOLL is available now!

An action-thriller novel — book 2 in the KESTREL series.

★★★★★ — Amazon


development & source 1 min read

Thanks to a comment by Todd Yandell on my recent gripe about NSViewAnimation, I give you: MGViewAnimation.

It’s a partial rework of Todd’s NSAnimation Demo code, which subclasses NSAnimation directly and updates all the animated views’ frames itself in the same thread for better perceived performance. For basic “animate a bunch of views at once” uses, you should be able to just change NSViewAnimation to MGViewAnimation and go with it. Go grab the source code from my Cocoa Source Code page now.

At the very least it’s a good starting point for folk having issues with NSViewAnimation, and just as a general example. I hope someone finds it useful, and a big thanks again to Todd for his original code.

Update: MGViewAnimation now does fade-in and fade-out effects too, and will now work with windows as well as views. Hopefully any existing code which uses NSViewAnimation should work as desired with an MGViewAnimation instead, and you should be able to cast between the two classes without problems.

One implementation note which may or may not affect you: the fades for views are done via adding an NSImageView into the relevant view’s superview, ordered in front of the view itself. Appropriately-dissolved images of the original view are set during animation progress. These view-images are updated during progress; if you don’t care about updating the view’s image during the animation, you can use [anim setContinuouslyUpdatesFadingViews:NO]; to always use an image of the view as it looked at the start of the animation.

As with NSViewAnimation, MGViewAnimation will take care of leaving the relevant view in a sensible hidden or shown state after the animation finishes, and telling the relevant window to orderFront: or orderOut: as appropriate, depending on the type of fade effect applied. If you wish to prevent a fading-out window from being sent orderOut: upon completing its fade, you can use [anim setOrdersOutFadedWindows:NO]; and the window will remain in the screen list. I do this in the included demo application, to make it easier to play with.