2012-10-09 21 views
3

我正在嘗試創建動畫行爲,其中視圖順時針旋轉45度,然後在用戶將其中心拖動到特定行上方時添加一個紅色圓圈。將同一視圖拖回到同一行下方會將其恢復到其原始方向,然後移除紅色圓圈。視圖應該採取3秒與動畫曲線UIViewAnimationCurveEaseInOut旋轉45度:在Objective-C for iOS中創建具有完成塊的可中斷動畫?

Visualization of desired behavior

我有體現此問題,- (void)viewHasMovedAboveLine:(UIView *)view- (void)viewHasMovedBelowLine:(UIView *)view,當視圖的上方或線下拖動被稱爲兩個功能由用戶。這兩個函數都包含具有完成處理程序的動畫,即+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion。完成處理程序根據需要添加或刪除紅色圓圈。

我能得到動畫如果用戶碰巧拖動視圖背面穿過線,而它是在動畫中的中間通過設置options:UIViewAnimationOptionBeginFromCurrentState並通過檢查的view.layer.animationKeys.count值之前執行所述動畫正常旋轉並刪除所有動畫,如果有任何正在執行通過[view.layer removeAllAnimations]

但是,即使在使用[view.layer removeAllAnimations]時,先前動畫的完成處理程序似乎仍然執行。 如果該動畫當前正在執行,是否有辦法停止動畫及其完成處理程序?

我更喜歡比爲每個動畫創建私有屬性更優雅的東西,例如@property (nonatomic) BOOL animation01IsCurrentlyExecuting@property (nonatomic) BOOL animation02IsCurrentlyExecuting。理想的解決方案將涵蓋包含動畫代碼和完成處理程序的各種動畫場景。

ALSO:有沒有辦法看到動畫在被中斷的時候有多遠?我自己對時間更感興趣(例如,動畫在2.1秒後中斷),以便我可以確保任何進一步的動畫都能正確計時。

+2

難道你不能只在你的完成處理程序中檢查'finished'參數嗎? – omz

+0

哇,這很容易。我從根本上誤解了(BOOL完成)是如何被使用的。請添加爲答案,我會批准? –

+0

另外,動畫中斷時,有沒有辦法找出動畫的進展程度? (添加上面作爲編輯) –

回答

1

UIView動畫塊的'finished'參數對於這種情況非常有用。

[UIView animateWithDuration:0.5 animations:^{ 
    //set your UIView's animatable property 
} completion:^(BOOL finished) { 
    if(finished){ 
     //the animation actually completed 
    } 
    else{ 
     //the animation was interrupted and did not fully complete 
    } 
}]; 

爲了找出在被打斷之前動畫進行了多長時間,NSDate上的一些方法可以派上用場。

__block NSDate *beginDate = [NSDate new]; 
__block NSTimeInterval timeElapsed; 

[UIView animateWithDuration:0.5 animations:^{ 
    //your animations 
    beginDate = [NSDate date]; 
} completion:^(BOOL finished) { 
    if(finished){ 
     //the animation actually completed 
    } 
    else{ 
     //the animation was interrupted and did not fully complete 
     timeElapsed = [[NSDate date] timeIntervalSinceDate:beginDate]; 
     NSLog(@"%f", timeElapsed); 
    } 
}];