animationDidStop用于组animation
我有一个组animation,但我无法检测何时点击animationDidStop。 我的代码示例:
[group setDelegate:self]; [view.layer addAnimation:group forKey:@"groupAnimation"];
你们谁知道我怎么知道什么时候组animation完成?
您还需要将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 } } }
请注意,对于组animation,在组件animation上设置的代表将被忽略。
我使用这个类别来设置完成,如下所示:
[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
我想出了一种组织好的animation完成代码的方法。 首先,我为animation完成时要运行的代码块定义了一个自定义types:
typedef void (^animationCompletionBlock)(void);
我定义了一个常量,用于将一个自定义的键值对添加到我的animation中:
#define kAnimationCompletionBlock @"animationCompletionBlock"
然后,当我创build一个animation时,如果我想在它完成时执行一个代码块,我添加一个自定义属性到我的animation,其中包含我要执行的代码块:
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];
我将视图控制器设置为animation的委托:
myAnimation.delegate = self
最后,我编写了一个通用的animation完成方法,该方法查找附加到animation的animation完成块,如果发现它,则执行它:
/* 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(); }
除了非常干净之外,这种方法还可以让您的animation完成代码访问位于您定义块的范围内的局部variables。 这解决了将信息传递给完成方法的问题,这可能很困难。
您可以在我发布到Github的示例程序中看到这个技巧:
Github上的Core Animation演示,包括完成块代码