animating a non-interpolated view property and totally confused
-
I'm trying to use Core/Cocoa Animation to coordinate
animating a property that my view must interpolate
itself. I want to animate whenever an enumeration
property gets changed, eg setTypeOfObject:kSquare when
it was a kCircle. So my view needs to know how far it
is between two enum values and figure out how to draw
something that is X% a kSquare and (1-X)% a kCircle on
its own.
My understanding is that in this case I need to
implement animationForKey: in my NSView subclass,
which must return an instance of CAAnimation. But it's
NSAnimation that has all the features I'm after, and
it's a subclass of NSObject that couldn't pose as a
CAAnimation. So I guess the CAAnimation would have my
view instance set as a delegate, and I'd need to make
my view's animationDidStart: delegate method start an
NSAnimation instance?
If that weren't convoluted enough, NSAnimation doesn't
use a delegate for something as basic as a progress
update. The Animation Programming Guide for Cocoa says
to subclass NSAnimation and override the
setCurrentProgress: method. Since my NSView instance
is the delegate anyway for the
animationShouldStart:/DidStop: methods, I implemented
this as:
-
(void)setCurrentProgress:(NSAnimationProgress)progress
{
[super setCurrentProgress:progress];
id delegate = [self delegate];
if ([delegate
respondsToSelector:@selector(animation:didProgressTo:)])
[delegate animation:self didProgressTo:progress];
}
However, to get the NSAnimation subclass to compile
without warnings, my NSView subclass needs to make its
animation:didProgressTo: method public. Even with the
delegate instead of an outlet shortcut, this is
getting very convoluted.
To top this all off, I still don't know where I would
look to get the property value I should be animating
"towards". When I've called [[myView animator]
setEnumerationValue:targetSetting], which object in
this soup can tell my view what targetSetting is?
Am I on the wrong track here? If I really have to
subclass NSAnimation, instantiate (and subclass??)
CAAnimation, and spaghetti everything together in a
bunch of view delegate methods just to get a steady
stream of progress values as a result of a property
change, I'd be better off sticking with my own
property accessors and an NSTimer.
thanks for any pointers,
-natevw
____________________________________________________________________________________
¡Capacidad ilimitada de almacenamiento en tu correo!
No te preocupes más por el espacio de tu cuenta con Correo Yahoo!:
http://correo.espanol.yahoo.com/ -
On Feb 13, 2008, at 6:07 PM, Nathan Vander Wilt wrote:
> My understanding is that in this case I need to
> implement animationForKey: in my NSView subclass,
> which must return an instance of CAAnimation. But it's
> NSAnimation that has all the features I'm after, and
> it's a subclass of NSObject that couldn't pose as a
> CAAnimation. So I guess the CAAnimation would have my
> view instance set as a delegate, and I'd need to make
> my view's animationDidStart: delegate method start an
> NSAnimation instance?
What you need to do is implement a "squareness" property on your view
that basically says how far you are between Square and Circle. When
you are asked to animate, you return a CABasicAnimation - you don't
need to modify it at all, just let setTypeOfObject do the work for you
to either say Square or Circle as the extreme of your "squareness"
property.
Then you will just be called periodically to draw, with "squareness"
linearly interpolated between the starting and ending value. As long
as you can draw the intermediate interpolations, you'll see your
animation progress.
--
David Duncan
Apple DTS Animation and Printing
<david.duncan...> -
--- David Duncan <david.duncan...> escribió:
> What you need to do is implement a "squareness"
> property on your view
> that basically says how far you are between Square
> and Circle. When
> you are asked to animate, you return a
> CABasicAnimation - you don't
> need to modify it at all, just let setTypeOfObject
> do the work for you
> to either say Square or Circle as the extreme of
> your "squareness"
> property.
Thanks much! With that direction I was able to figure
it pretty much out. I added a +defaultAnimationForKey:
method to my custom view, and made my enumeration
setter store the old value [there are actually more
than two possible enumerated states, and I should come
clean and say the property isn't really a C
enumeration, but my own "state" class] and then call
the "betweenness" setter through the animation proxy.
This gets me the stream of redraw requests I was
hoping for.
Now that I've got the basics working, I do have two
follow-up questions:
1) I want to set my view instance as a delegate of the
CABasicAnimation. It seems the only practical way to
to this is to override the -animationForKey: method,
but the NSAnimatablePropertyContainer protocol
documentation for that says "Subclasses should not
typically need to override this method." So long as I
pass any keys I don't handle to super, is this okay to
do?
2) I'd really like the controller, not the view, to
determine whether or not a property is animated.
However, when I refactor the [[self animator]
setBetweenness:1.0] call in the view's
setTypeOfObject: to instead be a [[myView animator]
setTypeOfObject:kTriangle] call in the controller, the
animation system doesn't animate the view's internal
[self setBetweenness:1.0] property change.
How can I arrange things so that the controller can
decide whether/not to use the proxy animator, but
still access the property via the primary
("typeOfObject") key?
thanks,
-natevw
____________________________________________________________________________________
¡Capacidad ilimitada de almacenamiento en tu correo!
No te preocupes más por el espacio de tu cuenta con Correo Yahoo!:
http://correo.espanol.yahoo.com/



