有很多细节需要注意,但总的想法是创建一个非重复动画,在完成后将其删除,然后使用 animationDidStop
代理方法重新启动动画。
首先要声明一些属性。
@property (weak, nonatomic) IBOutlet UIImageView *orangeView2;
@property (nonatomic) bool pulseActive;
@property (strong, nonatomic) CAKeyframeAnimation *pulseAnimation;
第一个属性是需要进行动画处理的视图,第二个属性用于跟踪动画是否已启用,最后一个属性是实际的动画(存储在属性中,以便我们只需实例化一次)。
接下来,我们将使用延迟实例化来创建动画对象。
- (CAKeyframeAnimation *)pulseAnimation
{
if ( !_pulseAnimation )
{
_pulseAnimation = [CAKeyframeAnimation animationWithKeyPath:@"opacity"];
_pulseAnimation.values = @[ @0.0f, @1.0f, @0.0f ];
_pulseAnimation.duration = 0.5;
_pulseAnimation.delegate = self;
[_pulseAnimation setValue:@"PulseAnimation" forKey:@"AnimationIdentifier"];
}
return( _pulseAnimation );
}
重要的部分如下:
- 默认情况下,动画不会重复播放。
- 默认情况下,动画会在完成后被移除。
- 将
delegate
设置为 self
,以便调用 animationDidStop
方法。
- 使用
setValue:forKey:
为动画设置标识符。
如果多个动画使用相同的委托,则需要最后一项。在这种情况下,您需要一种方法来确定哪个动画调用了
animationDidStop
。传递给
forKey
和
setValue
的字符串是任意的,并存储在动画对象的字典中。
现在我们需要实现
animationDidStop
。该实现检查
pulseActive
属性,并在必要时重新启动动画(在检查动画的身份后)。
- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)flag
{
NSString *animationIdentifier = [animation valueForKey:@"AnimationIdentifier"];
if ( [animationIdentifier isEqualToString:@"PulseAnimation"] )
{
if ( self.pulseActive )
[self.orangeView2.layer addAnimation:self.pulseAnimation forKey:@"pulsate"];
}
}
现在要做的就是开始和停止动画。例如,一个可以切换动画的按钮。
- (IBAction)pulseButtonPressed
{
if ( !self.pulseActive )
{
self.pulseActive = YES;
[self.orangeView2.layer addAnimation:[self pulseAnimation] forKey:@"pulsate"];
}
else
{
self.pulseActive = NO;
}
}