我遇到了一个问题,我有一系列重叠的CATransition / CAAnimation序列,所有这些序列都需要在动画停止时执行自定义操作,但我只想要一个用于animationDidStop的委托处理程序。
但是,我遇到了一个问题,似乎没有一种方法可以唯一地标识animationDidStop委托中的每个CATransition / CAAnimation。
我通过作为CAAnimation的一部分公开的键/值系统解决了这个问题。
开始动画时,在CATransition / CAAnimation上使用setValue方法来设置要在触发animationDidStop时使用的标识符和值:
-(void)volumeControlFadeToOrange
{
CATransition* volumeControlAnimation = [CATransition animation];
[volumeControlAnimation setType:kCATransitionFade];
[volumeControlAnimation setSubtype:kCATransitionFromTop];
[volumeControlAnimation setDelegate:self];
[volumeControlLevel setBackgroundImage:[UIImage imageNamed:@"SpecialVolume1.png"] forState:UIControlStateNormal];
volumeControlLevel.enabled = true;
[volumeControlAnimation setDuration:0.7];
[volumeControlAnimation setValue:@"Special1" forKey:@"MyAnimationType"];
[[volumeControlLevel layer] addAnimation:volumeControlAnimation forKey:nil];
}
- (void)throbUp
{
doThrobUp = true;
CATransition *animation = [CATransition animation];
[animation setType:kCATransitionFade];
[animation setSubtype:kCATransitionFromTop];
[animation setDelegate:self];
[hearingAidHalo setBackgroundImage:[UIImage imageNamed:@"m13_grayglow.png"] forState:UIControlStateNormal];
[animation setDuration:2.0];
[animation setValue:@"Throb" forKey:@"MyAnimationType"];
[[hearingAidHalo layer] addAnimation:animation forKey:nil];
}
在您的animationDidStop代理中:
- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag{
NSString* value = [theAnimation valueForKey:@"MyAnimationType"];
if ([value isEqualToString:@"Throb"])
{
//... Your code here ...
return;
}
if ([value isEqualToString:@"Special1"])
{
//... Your code here ...
return;
}
//Add any future keyed animation operations when the animations are stopped.
}
另一方面,它允许您将状态保存在键值配对系统中,而不必将其存储在委托类中。代码越少越好。
请务必查看Apple Reference on Key Value Pair Coding。
在animationDidStop委托中是否有更好的CAAnimation / CATransition标识技术?
谢谢,--巴特加
发布于 2009-09-07 21:14:40
巴特加的技术太复杂了。为什么不利用addAnimation中的forKey参数呢?它的目的就是为了这个目的。只需取出对setValue的调用,并将密钥字符串移动到addAnimation调用。例如:
[[hearingAidHalo layer] addAnimation:animation forKey:@"Throb"];
然后,在您的animationDidStop回调中,您可以执行以下操作:
if (theAnimation == [[hearingAidHalo layer] animationForKey:@"Throb"]) ...
发布于 2012-01-06 03:24:24
我只是想出了一种更好的方法来完成CAAnimations的代码:
我为一个块创建了一个类型定义函数:
typedef void (^animationCompletionBlock)(void);
和一个我用来向动画添加块的键:
#define kAnimationCompletionBlock @"animationCompletionBlock"
然后,如果我想要在CAAnimation完成后运行动画完成代码,我将自己设置为动画的代理,并使用setValue:forKey向动画添加一段代码:
animationCompletionBlock theBlock = ^void(void)
{
//Code to execute after the animation completes goes here
};
[theAnimation setValue: theBlock forKey: kAnimationCompletionBlock];
然后,我实现了一个animationDidStop:finished:方法,它检查指定键处的块,如果找到就执行它:
- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag
{
animationCompletionBlock theBlock = [theAnimation valueForKey: kAnimationCompletionBlock];
if (theBlock)
theBlock();
}
这种方法的美妙之处在于,您可以在创建动画对象的相同位置编写清理代码。更好的是,因为代码是一个块,所以它可以访问定义它的封闭作用域中的局部变量。您不必费心设置userInfo字典或其他类似的胡言乱语,也不必编写一个不断增长的动画don:finished:方法,当您添加不同种类的动画时,该方法会变得越来越复杂。
说实话,CAAnimation应该有一个内置的完成块属性,并且系统支持在指定的情况下自动调用它。但是,上面的代码只需要几行额外的代码就可以提供相同的功能。
发布于 2011-02-16 06:30:56
为了明确上面所暗示的(以及浪费了几个小时才让我来到这里的原因):不要期望看到您分配的原始动画对象通过
- (void)animationDidStop:(CAAnimation*)animation finished:(BOOL)flag
动画结束时,因为[CALayer addAnimation:forKey:]
会制作动画的副本。
您可以依赖的是,您为动画对象提供的键值仍然与animationDidStop:finished:
消息传递的副本动画对象中的等效值(但不一定是指针等效值)存在。如上所述,使用KVC可以获得足够的范围来存储和检索状态。
https://stackoverflow.com/questions/1255086
复制相似问题