如何取消 UIView 動畫?


原文鏈接

最近項目中有一個需求是需要手動點擊相機對焦,這里由於相機對焦部分需要一個類似於系統對焦框一樣的縮放動畫,同時動畫時長為0.3秒,因此這里就有一個很普遍的需求,如果用戶在0.3秒內繼續點擊對焦會怎么樣?

動畫部分代碼很簡單,如下:

self.transform = CGAffineTransformMakeScale(2.0f, 2.0f);
    [UIView animateWithDuration:0.3f delay:0.0f options:UIViewAnimationOptionCurveLinear
                     animations:^{
                         self.transform = CGAffineTransformIdentity;
                     }
                     completion:^(BOOL finished){
                         if (finished) {
                             [self hideFocus];
                         }
                     }];

對焦框在0.3秒內進行兩倍縮小到正常尺寸的一個動畫,之后隱藏。

舊代碼分析

以前的代碼在這部分的處理大致是這樣的,

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(touchFocus:) object:_touches];
    
    UITouch *touch = [_touches anyObject];
    CGPoint touchPoint = [touch locationInView:self.view];


    [self performSelector:@selector(touchFocus:) withObject: touches afterDelay:0.3f];
    
- (void)touchFocus:(NSSet *)touches {
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(touchFocus:) object:touches];
    
    // 以下為具體對焦框顯示部分
    ...
}

可以看出,代碼邏輯大致為,截獲屏幕點擊事件,之后加入一個0.3秒的延時方法,如果用戶0.3秒內再次點擊對焦,則取消上一次的對焦事件;否則,執行對焦框動畫。

這個邏輯看似解決了用戶快速點擊對焦的問題,實際上如果用戶真正快速點擊屏幕時,會出現一個很奇怪的現象,就是對焦框始終存在,並且不會變換位置,等到停止點擊屏幕后,對焦框才會響應最新的觸控位置進行動畫,另一個問題就是對焦始終存在遲滯感,因為點擊屏幕后需要等待0.3秒才能看到動畫。

解決方案

那么有什么更好的辦法呢?系統難道沒有提供終止動畫的接口嘛?當然不是,其實只需要在用戶再次點擊屏幕時候調用[_focusView.layer removeAllAnimations];即可,其中具體的 view 為正在做動畫的 view。

這樣做還有另外一個好處,再也不需要煩人的滯后感了,屏幕對焦始終跟手,同時直接終止動畫,里面的 completion 都會照常調用,不存在副作用,很好地解決了這個問題。

新引入問題

最近遇到了一個新引入的問題,發現對焦框無法隱藏,經過調查,問題出在這里:

if (finished) {
    [self hideFocus];
}

如果是直接使用removeAllAnimations接口停止動畫的話,此處的finished參數有可能返回 NO,導致這段代碼產生問題,所以這里如果中止動畫,則需要重新進行判定。

總結

  • 學會了 removeAllAnimations接口用法

盡管這個是很基礎的系統 API 調用,但是我之前一直都不知道,在此記錄下來,希望能給予其他人些許幫助。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM