Re: NSAnimatablePropertyContainer
Re: NSAnimatablePropertyContainer
- Subject: Re: NSAnimatablePropertyContainer
- From: Troy Stephens <email@hidden>
- Date: Fri, 16 Nov 2007 10:15:38 -0800
On Nov 16, 2007, at 9:49 AM, I. Savant wrote:
On 11/16/07, Troy Stephens <email@hidden> wrote:
The way the code is written now, [[myCustomView animator]
setImageAlpha:0.0] queues up an animation from the present value to
0.0 (which won't begin executing until control returns to the
runloop). Then [[myCustomView animator] setImageAlpha:1.0] schedules
another animation to 1.0 that supersedes the animation to 0.0.
Almost
certainly the reason that changes to "imageToDisplay" after the first
fail to animate is that imageAlpha is already 1.0, so the animation
to
1.0, the one that replaces the animation to 0.0, has nothing to do.
I sort of figured that's another part of what was going on (never
mind that the image old image is no longer there the next time the
view is asked to draw), but maybe I should clarify a bit. I want the
following to happen when a new image is set:
1 - Fade the old image out.
2 - Swap images.
3 - Fade the new image in.
This requires the ability to set up a blocking animation, which (as
suggested off-list) does not seem possible. In the same off-list
response, I was told (paraphrasing) I should probably be forgetting
about the alpha and just use a CATransition (fade) between old and new
images.
Even with that, though, the problem remains. I can't fade the old
image out and the new one in asynchronously because the image changes
before the animation is started. I can't help feeling I'm missing
something ridiculously obvious.
If you're using layer-backed views, then the CATransition approach is
definitely the path of least resistance. See the "SlideshowView"
class in the Cocoa Slides code sample, which demonstrates how to apply
any of the available transition styles to a subview swap:
http://developer.apple.com/samplecode/CocoaSlides/
A simple fade-out, fade-in as you describe could also be implemented
without using layers, in a variety of ways. As you noted, the
"animator"-proxy-based animation facility deals exclusively in
asynchronous animations. You could use the NSAnimation API to
implement a blocking animation, but you probably don't really want to
block your UI for the duration of the animation. Using the animator
approach, you could, for example, animate a custom
"transitionProgress" property from 0.0 to 1.0, and have your view's -
drawRect: do something like:
[[NSColor whiteColor] set];
NSRectFill(rect);
float t = [self transitionProgress];
if (t < 0.5) {
[oldImage drawAtPoint:NSZeroPoint fromRect:NSZeroRect
operation:NSCompositeSourceOver fraction:(2.0 * (0.5 - t))];
} else {
[newImage drawAtPoint:NSZeroPoint fromRect:NSZeroRect
operation:NSCompositeSourceOver fraction:(2.0 * (t - 0.5))];
}
That's one way it could be done. Obviously you'd need to hold onto
the old image for the duration of the transition, and you'd probably
want some way for the view to be able to report whether it's in the
middle of executing a transition to a new image, so that client code
can plan timing accordingly. But again, if you're using layer-backed
views, then using a CATransition is the easy way to go. See
CocoaSlides for how to do that.
Troy
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden