Re: CALayer/CAAnimation doesn't animate
Re: CALayer/CAAnimation doesn't animate
- Subject: Re: CALayer/CAAnimation doesn't animate
- From: Bill Dudney <email@hidden>
- Date: Tue, 15 Jan 2008 13:54:04 -0700
Hi Joachim,
On Jan 15, 2008, at 7:38 AM, Joachim wrote:
Bill, Scott,
Thanks for setting this straight! This was a great help. Having read
the documentation numerous times, I still wasn't clear on how to add
my own root layer in a layer-hosting view. I thought I could "reuse"
the layer-backed view layer, set in IB and/or code. Apparently not.
Also, animating the wrong property doesn't exactly make things
happen either. :-)
The reason I use a layer-hosted view and explicit animations is
because I need some more complicated animations to happen and
several of them. As many as 30-40 layers animating at a time. The
code below is just to make even a simple animation work for me.
I now got the layer to move, but a few more problems remain...
- (void)animateNewLayer
{
// Create animating layer
CALayer *layer = [CALayer layer];
// Configure layer
layer.anchorPoint = CGPointMake (0, 0); // Use lower/left corner
as with views
layer.frame = CGRectMake (0, 0, 24, 24);
layer.contents = myCGImageRef; // Created earlier in this method
CGImageRelease (myCGImageRef);
// If we don't have a root layer, create and set it
if (!self.layer) {
[self setLayer:[CALayer layer]];
[self setWantsLayer:YES];
}
[[self layer] addSublayer:layer]; // Add our animating sublayer
// Create animation
CABasicAnimation *anim = [CABasicAnimation
animationWithKeyPath:@"position"];
// Configure animation
anim.fromValue = [NSValue valueWithPoint:NSMakePoint (0, 0)];
anim.toValue = [NSValue valueWithPoint:NSMakePoint (100,
100)];
anim.timingFunction = [CAMediaTimingFunction
functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
anim.duration = 2.0;
animation.fillMode = kCAFillModeForwards;
anim.delegate = self;
// Add animation to layer; also triggers the animation
[layer addAnimation:anim forKey:@"position"];
}
I think I'm now setting the root layer as I should. If the root
layer doesn't exist, I create and add it to the hosting view and
then add and remove sublayers in the lifetime of the view as needed.
The hosting view never goes away, and so neither does the root layer
once it's added.
These are the problems I see:
1) When the layer starts animating, the hosting view dissapears and
never reappears (this also happened in the original code)
Hm... are you drawing into the view? That is another no-no, once you
take over the layer of a view you should not draw in it (with the
drawRect: method) but instead do all your drawing via the layer.
2) Setting the fillMode to kCAFillModeForwards still makes the layer
jump back to its original position (or opacity or whatever I animate
on) after the animation is done
Not sure what this is all about. Are you ever setting the value or
just depending on the animation to set it for you?
Once again, thank you for taking the time.
my pleasure - HTH,
-bd-
http://bill.dudney.net/roller/objc
Joachim
On 15-Jan-08, at 9:10 AM, Scott Anguish wrote:
On Jan 14, 2008, at 6:07 PM, Bill Dudney wrote:
Hi Joachim,
You should not be manipulating the layer that the view creates for
its self as a general rule.
True.
If you don't create it and set it, you shoudn't mess with it.
If you call [self setLayer:[CALayer layer]] right before you call
[self setWantsLayer:YES] you should start to see behavior that
more closely matches what you want/expect.
This is how you should always do it. Set the layer to your
requested layer class, then enabled layers.
But, no, you won't see the behavior you expect.
CABasicAnimation *anim = [CABasicAnimation
animationWithKeyPath:@"frameOrigin"];
// Configure animation
anim.fromValue = [NSValue valueWithPoint:NSMakePoint (0, 0)];
anim.toValue = [NSValue valueWithPoint:NSMakePoint (100,
100)];
anim.timingFunction = [CAMediaTimingFunction
functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
anim.duration = 2.0;
anim.delegate = self;
// Add animation to layer; also triggers the animation
[layer addAnimation:anim forKey:@"frameOrigin"];
oints 1 - frameOrigin isn't a property of CALayer. position is.
You can only animate properties of a layer that exist, and that are
marked as animatable in the CALayer class. conceptual doc does
cover this. Perhaps you're confusing with the view frameOrigin
method?
point 2 - you're using explicit animation and you're using the
default fillMode (kCAFillModeRemoved). This causes the explicit
animation to be removed when the animation is over. So you blink,
and it's gone back to the start point.
BTW, I'm not sure you want an explicit animation in this case
anyways.. you'd expect that the layer would keep its 100,100
location, wouldn't you? in that case you could just use implicit
animation. If you really want the different timing function than
the default you can change the implicit animation for the "frame"
property.
point 3 is because you're using the wrong delegate method if you're
using animationDidStop: this isn't a CALayer delegate method.
animationDidStop:finished: is.
_______________________________________________
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
_______________________________________________
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