在動畫過程中取消動畫(顯式動畫),動畫取消
在動畫過程中取消動畫
之前提到過,你可以用-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)viewDidLoad11 {12 [super viewDidLoad];13 //add the ship14 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)start22 {23 //animate the ship rotation24 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)stop33 {34 [self.shipLayer removeAnimationForKey:@"rotateAnimation"];35 }36 37 - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag38 {39 //log that the animation stopped40 NSLog(@"The animation stopped (finished: %@)", flag? @"YES": @"NO");41 }42 43 @end
View Code
圖8.6 通過開始和停止按鈕控制的旋轉動畫