Cocoa Animation Proxy “woes”

Both, NSWindow and NSView offer a convenient way to add animation to your UI by the use of animation proxies. But there are some “woes” you have to keep in mind.

E.g. if you want to switch the visibility state you normally use:

[aView setHidden:YES]; // Hide the view
// very important code....
[aView setHidden:NO]; // Un-Hide the view

To do the same thing with a short and smooth animation, you just have to change the above code to the following:

[[aView animator] setHidden:YES]; // Hide the view with animation
// very important code....
[[aView animator] setHidden:NO]; // Un-Hide the view with animation

(For some animations, like subview transitions, aView has to be layer-backed which can be accomplished with a call to [aView setWantsLayer:YES];)

So far so good. But what, if aView is a custom subclass of NSView, NSBox or whatsoever?

Normally, this is not a problem, since the object returned by [aView animator] is a proxy object for the original object and can be treated as if it was the original object itself.

But, there is a difference! If you call setHidden:YES on the original object, it gets called, regardless of the actual “hidden-state” of the view. If you call it on the proxy-object, it gets called only, if the value really changes. So calling setHidden:YES on an animator-proxy, which original-object is already hidden, has no effect at all.

This behavior can be ignored, as long as you do not overwrite any of the methods that change animateable properties, like setHidden:. But if you do, keep in mind, that your overwritten method may not be called while using the animator-proxy. In some cases, were you depend upon the fact, that your method gets always called, this can be a problem e.g. if you always want to do something in your setter, regardless of what the actual state or value is.

Leave a Reply