How to remove a layer when its animation completes?

Question:

I am making an iOS App. I have several CALayer objects that eventually will be deleted by a (shrinking) animation. When the animation is completed, and animationDidStop:finished is invoked, I would like to remove the CALayer object from the super view and delete it. 

  1. But how can I get the CALayer object in animationDidStop:finished? I would have guessed that the CAanimation-object had a pointer to the layer, but I can't find it in the doc. 
  2. Is there a better way to handle the issue? (Actually, I have several animation objects added to the same layer, and, ideally, I would like to remove the layer only when the last animation completes)


Answers




As for removing all the animations, you have two options:

  1. You can check your CALayer's animationKeys for any existing animations.
  2. You can use a CAAnimationGroup and group all your animations together.

I am invoking  addAnimation:forKey:, how can I pass a CALayer object? –   ragnarius  Jul 16 '13 at 23:29
1  
You could have a NSMutableArray property on your delegate. Any time you use addAnimation:forKey: add that CALayer to the NSMutableArray. Then you can reference all the CALayers from your delegate. –  Patrick Tescher  Jul 16 '13 at 23:34
 
So you mean that animationDidStop:finished: should scan through that mutable array to see if it can find any layer objects that has no ongoing animations, and then remove them from both the array and the super layer? –   ragnarius  Jul 16 '13 at 23:45
 
Yes, or if all your animations are on a single CALayer you can skip the NSMutableArray. CAAnimations are pretty low level. They don't take car of much other than animating. Thats why the UIView block animations are more common. –   Patrick Tescher  Jul 17 '13 at 0:30



See if this answer helps: Perform an action after the animation has finished I find animateWithDuration:animations:completion: to be way easier to use than working directly with CALayer. You can chain multiple animations via the completion handler and then remove the layer in the last one. eg:

[UIView animateWithDuration:1.0 animations:^{
    // do first animation in the sequence
} completion:^(BOOL finished) {
    [UIView animateWithDuration:1.0 animations:^{
        // do second animation in the sequence
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:1.0 animations:^{
            // do third animation in the sequence
        } completion:^(BOOL finished) {
            // remove layer after all are done
        }];
    }];
}];

Possibly a little messy this way, but you could refactor these into their own method calls, for instance.





One alternativ solution is to add a layer pointer to the animation object's dictionary, as follows

// in some define section
#define kAnimationRemoveLayer @"animationRemoveLayer"

then, in the animationDidStop,

- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag{
    CALayer *lay = [theAnimation valueForKey:kAnimationRemoveLayer];
    if(lay){
        [lay removeAllAnimations];
        [lay removeFromSuperlayer];
    }
}

and, finally, in the animation setup,

CALAyer * lay = ... ;
BOOL    shouldRemove = .... ; 
CABasicAnimation* anim = [CABasicAnimation animationWithKeyPath:@"position"];
anim.delegate = self;
if (shouldRemove)
    [anim setValue:lay forKey:kAnimationRemoveLayer];

转载:http://stackoverflow.com/questions/17688440/how-to-remove-a-layer-when-its-animation-completes

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值