之前提到过,你可以用-addAnimation:forKey:
方法中的key
参数来在添加动画之后检索一个动画,使用如下方法:
- (CAAnimation *)animationForKey:(NSString *)key;
但并不支持在动画运行过程中修改动画,所以这个方法主要用来检测动画的属性,或者判断它是否被添加到当前图层中。
为了终止一个指定的动画,你可以用如下方法把它从图层移除掉:
- (void)removeAnimationForKey:(NSString *)key;
或者移除所有动画:
- (void)removeAllAnimations;
动画一旦被移除,图层的外观就立刻更新到当前的模型图层的值。一般说来,动画在结束之后被自动移除,除非设置removedOnCompletion
为NO
,如果你设置动画在结束之后不被自动移除,那么当它不需要的时候你要手动移除它;否则它会一直存在于内存中,直到图层被销毁。
我们来扩展之前旋转飞船的示例,这里添加一个按钮来停止或者启动动画。这一次我们用一个非nil
的值作为动画的键,以便之后可以移除它。-animationDidStop:finished:
方法中的flag
参数表明了动画是自然结束还是被打断,我们可以在控制台打印出来。如果你用停止按钮来终止动画,它会打印NO
,如果允许它完成,它会打印YES
。
清单8.15是更新后的示例代码,图8.6显示了结果。
清单8.15 开始和停止一个动画
1 @interface ViewController () 2 3 @property (nonatomic, weak) IBOutlet UIView *containerView; 4 @property (nonatomic, strong) CALayer *shipLayer; 5 6 @end 7 8 @implementation ViewController 9 10 - (void)viewDidLoad 11 { 12 [super viewDidLoad]; 13 //add the ship 14 self.shipLayer = [CALayer layer]; 15 self.shipLayer.frame = CGRectMake(0, 0, 128, 128); 16 self.shipLayer.position = CGPointMake(150, 150); 17 self.shipLayer.contents = (__bridge id)[UIImage imageNamed: @"Ship.png"].CGImage; 18 [self.containerView.layer addSublayer:self.shipLayer]; 19 } 20 21 - (IBAction)start 22 { 23 //animate the ship rotation 24 CABasicAnimation *animation = [CABasicAnimation animation]; 25 animation.keyPath = @"transform.rotation"; 26 animation.duration = 2.0; 27 animation.byValue = @(M_PI * 2); 28 animation.delegate = self; 29 [self.shipLayer addAnimation:animation forKey:@"rotateAnimation"]; 30 } 31 32 - (IBAction)stop 33 { 34 [self.shipLayer removeAnimationForKey:@"rotateAnimation"]; 35 } 36 37 - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag 38 { 39 //log that the animation stopped 40 NSLog(@"The animation stopped (finished: %@)", flag? @"YES": @"NO"); 41 } 42 43 @endlogs_code_collapse">View Code
图8.6 通过开始和停止按钮控制的旋转动画