在動畫過程中取消動畫 之前提到過,你可以用-addAnimation:forKey:方法中的key參數來在添加動畫之後檢索一個動畫,使用如下方法: 但並不支持在動畫運行過程中修改動畫,所以這個方法主要用來檢測動畫的屬性,或者判斷它是否被添加到當前圖層中。 為了終止一個指定的動畫,你可以用如下方法把它 ...
在動畫過程中取消動畫
之前提到過,你可以用-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 @endView Code
圖8.6 通過開始和停止按鈕控制的旋轉動畫