2012-08-28 33 views
3

我有一个组动画,但无法检测何时点击animationDidStop。例如我的代码:animationDidStop for group animation

[group setDelegate:self]; 
[view.layer addAnimation:group forKey:@"groupAnimation"]; 

任你知道我怎么知道什么时候该组动画完成?

+1

__Be知道'CAAnimation'的'delegate'强,所以你可能需要将其设置为'nil'避免保留周期!__ –

回答

11

您还需要设置animationName属性相匹配,并确保您的委托功能正确定义:

CAAnimationGroup *group = [CAAnimationGroup animation]; 
group.duration = 2.0f; 
group.delegate = self; 
[group setValue:@"groupAnimation" forKey:@"animationName"]; 
[group setAnimations:[NSArray arrayWithObjects:myAnimation, myOtherAnimation, nil]]; 
[view.layer addAnimation:group forKey:@"groupAnimation"]; 

。 。 。

- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)finished 
{ 
if (finished) 
{ 
    NSString *animationName = [animation valueForKey:@"animationName"]; 
    if ([animationName isEqualToString:@"groupAnimation"]) 
    { 
    // your groupAnimation has ended 
    } 
} 
} 

请注意,使用组动画时,组件动画上设置的代表将被忽略。

+2

你可能应该解释一下,animationName是动画上的一个自定义属性(不是子类,而是当你使用setValue:forKey时被设置的属性)以及它为什么可以工作(Core Animation可以为任何值设置一个值其动画键(正常类不以这种方式工作))等 –

+0

是的,谢谢@DavidRonnqvist,animationName是任意属性,这里仅用于识别动画在animationDidStop委托方法完成。如果你只有一个动画正在进行,你在技术上不需要这个...但是你确实需要正确定义的委托方法,这是你可能的问题。 – CSmith

+0

完美解决方案!非常感谢 。它真的帮了我很多 – ShineWang

1

我想出了一种组织好的动画完成代码的方法。首先,我定义的自定义类型的代码块时的动画完成运行:

typedef void (^animationCompletionBlock)(void); 

我定义一个常数,我使用的自定义键值对添加到我的动画:

#define kAnimationCompletionBlock @"animationCompletionBlock" 

然后,当我创建一个动画,如果我想它,当它完成执行的代码块,我自定义属性添加到我的动画包含的代码块我要执行:

animationCompletionBlock theBlock; 
theBlock = ^void(void) 
{  
    someButton.enabled = TRUE; 
    NSLog(@"Animation complete"); 
    //whatever other code you want to do on completion 
} 

[myAnimation setValue: theBlock forKey: kAnimationCompletionBlock]; 

我设置了v IEW控制器是动画的委托:

myAnimation.delegate = self 

最后,我写看起来为附连到动画的动画完成块,并且如果它发现它执行它的通用动画完成方法:

/* 
This method looks for a value added to the animation that just completed 
with the key kAnimationCompletionBlock. 
If it exists, it assumes it is a code block of type animationCompletionBlock, 
and executes the code block. 
This allows you to add a custom block of completion code to any animation or 
animation group, rather than Having a big complicated switch statement in your 
animationDidStop:finished: method with global animation ompletion code. 
(Note that the system won't call the animationDidStop:finished method for 
individual animations in an animation group - it will only call the 
completion method for the entire group. Thus, if you want to run code after 
part of an animation group completes, you have to set up a manual timer.) 
*/ 

- (void)animationDidStop:(CAAnimation *)theAnimation 
    finished:(BOOL)flag 
{ 
    animationCompletionBlock theBlock = 
    [theAnimation valueForKey: kAnimationCompletionBlock]; 
    if (theBlock) 
    theBlock(); 
} 

除了非常干净之外,此方法还允许您的动画完成代码访问位于您定义块的范围内的局部变量。这解决了将信息传递给完成方法的问题,这可能很困难。

你可以看到在一个工作示例程序这个技术我发布到Github上:

Core Animation demo on Github, including completion block code

+0

随着swift3的一些更新,这肯定会是最优雅的动画。您可以创建几个扩展,将可以很容易地写一些东西,比如'addAnimation(动画,完成:)' –

2

我使用这个类别设置完成这样的:

[group setCompletionBlock:^{ 

}]; 

第一个CAAnimationGroup + Blocks.h:

#import <QuartzCore/QuartzCore.h> 
#import <objc/runtime.h> 

typedef void (^TIFAnimationGroupCompletionBlock)(); 

@interface CAAnimationGroup (Blocks) 

- (void)setCompletionBlock:(TIFAnimationGroupCompletionBlock)handler; 

@end 

而且CAAnimationGroup + Blocks.m:

#import "CAAnimationGroup+Blocks.h" 

static char CAAnimationGroupBlockKey; 

@implementation CAAnimationGroup (Blocks) 

- (void)setCompletionBlock:(TIFAnimationGroupCompletionBlock)handler { 
    objc_setAssociatedObject(self, &CAAnimationGroupBlockKey, handler, OBJC_ASSOCIATION_COPY_NONATOMIC); 

    self.delegate = self; 
} 

- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)finished 
{ 
    if (finished) 
    { 
     TIFAnimationGroupCompletionBlock handler = (TIFAnimationGroupCompletionBlock)objc_getAssociatedObject(self, &CAAnimationGroupBlockKey); 
     if (handler) { 
      handler(); 
     } 
    } 
} 

@end 
+0

我得到这个错误的'self.delegate =自我;' - 分配到“身份证 _Nullable”从不兼容的类型'CAAnimationGroup * const __strong' –