2008-11-17 78 views
46

我想知道CALayer中的動畫在哪裏(或者是否有任何動畫)。具體而言,隱含的動畫像改變框架,位置等。在一個UIView,你可以做這樣的事情:CALayer的動畫結束回調?

[UIView beginAnimations:@"SlideOut" context:nil]; 
[UIView setAnimationDuration:.3]; 
[UIView setAnimationDelegate:self]; 
[UIView setAnimationDidStopSelector:@selector(animateOut:finished:context:)]; 
CGRect frame = self.frame; 
frame.origin.y = 480; 
self.frame = frame; 
[UIView commitAnimations]; 

具體來說,setAnimationDidStopSelector就是我想要的CALayer的動畫。有沒有這樣的事情?

TIA。

+0

對於谷歌搜索的人在這裏,我已經把一個現代回答這個令人難以置信老問題! :O搜索到「2017 ...」 – Fattie 2017-11-28 16:47:05

回答

50

我回答了我自己的問題。你必須添加使用CABasicAnimation動畫像這樣:

CABasicAnimation* anim = [CABasicAnimation animationWithKeyPath:@"frame"]; 
anim.fromValue = [NSValue valueWithCGRect:layer.frame]; 
anim.toValue = [NSValue valueWithCGRect:frame]; 
anim.delegate = self; 
[layer addAnimation:anim forKey:@"frame"]; 

並實現委託方法animationDidStop:finished:,你應該是好去。謝天謝地,這個功能存在! :D

+2

此答案對於有關委託的信息很有用,但它有一個很大的缺陷 - 您無法爲「框架」設置動畫,因爲它是派生屬性。 http://developer.apple.com/library/mac/#qa/qa2008/qa1620.html – Michal 2010-10-13 08:15:16

0

設置CAAnimation對象時,可以設置給定動畫的名稱。在animationDiStop中:完成後,只需比較提供的動畫對象的名稱,以根據動畫執行特定的功能。

+1

沒有名稱屬性? – Andy 2014-05-19 21:30:44

104

您可以使用CATransaction,它有一個完成塊處理程序。

[CATransaction begin]; 
CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 
[pathAnimation setDuration:1]; 
[pathAnimation setFromValue:[NSNumber numberWithFloat:0.0f]];  
[pathAnimation setToValue:[NSNumber numberWithFloat:1.0f]]; 
[CATransaction setCompletionBlock:^{_lastPoint = _currentPoint; _currentPoint = CGPointMake(_lastPoint.x + _wormStepHorizontalValue, _wormStepVerticalValue);}]; 
[_pathLayer addAnimation:pathAnimation forKey:@"strokeEnd"]; 
[CATransaction commit]; 
+15

請注意,在將動畫添加到圖層之前,設置完成塊非常重要。 – Groot 2014-11-18 11:40:25

+0

這並不總是有用,因爲即使沒有完成,也會在刪除動畫時調用。 – 2018-03-04 20:11:39

8

只是說明對於那些誰在谷歌找到此頁:你真的能得到通過設置動畫對象的對象的「委託」屬性,將收到通知,並貫徹「animationDidStop完成任務「方法在該對象的.m文件中。我剛剛嘗試過,而且很有效。我不知道喬布洛爲什麼說這不是正確的方法。

+0

使用setCompletionBlock和CATransation.begin試圖從removeAllAnimations到具體的CAAnimations,並像user3077725的答案一樣提交。試過UIView.animateWIthDuration。沒有適用於簡單的alpha和position.x動畫。委託方法是唯一正常工作的 – KorinW 2016-03-13 03:56:07

44

用這個垃圾浪費了4個小時,只是淡入淡出。 請注意代碼中的註釋。

[CATransaction begin]; 
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"]; 
    animation.duration = 0.3; 
    animation.fromValue = [NSNumber numberWithFloat:0.0f]; 
    animation.toValue = [NSNumber numberWithFloat:1.0f]; 
    animation.removedOnCompletion = NO; 
    animation.fillMode = kCAFillModeBoth; 
    /// [box addAnimation:animation forKey:@"j"]; Animation will not work if added here. Need to add this only after the completion block. 

    [CATransaction setCompletionBlock:^{ 

     CABasicAnimation *animation2 = [CABasicAnimation animationWithKeyPath:@"opacity"]; 
     animation2.duration = 0.3; 
     animation2.beginTime = CACurrentMediaTime()+1; 
     animation2.fromValue = [NSNumber numberWithFloat:1.0f]; 
     animation2.toValue = [NSNumber numberWithFloat:0.0f]; 
     animation2.removedOnCompletion = NO; 
     animation2.fillMode = kCAFillModeBoth; 
     [box addAnimation:animation2 forKey:@"k"]; 

    }]; 

    [box addAnimation:animation forKey:@"j"]; 

    [CATransaction commit]; 
29

以下是雨燕3.0的答案基於bennythemink的解決方案:

// Begin the transaction 
    CATransaction.begin() 
    let animation = CABasicAnimation(keyPath: "strokeEnd") 
    animation.duration = duration //duration is the number of seconds 
    animation.fromValue = 0 
    animation.toValue = 1 
    animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) 
    circleLayer.strokeEnd = 1.0 

    // Callback function 
    CATransaction.setCompletionBlock { 
     print("end animation") 
    } 

    // Do the actual animation and commit the transaction 
    circleLayer.add(animation, forKey: "animateCircle") 
    CATransaction.commit() 
8

2018 ...

斯威夫特4.

在實踐中,你需要[weak self]或者你」通常會崩潰。

func animeExample() { 

    CATransaction.begin() 

    let a = CABasicAnimation(keyPath: "fillColor") 
    a.fromValue, duration = ... etc etc 

    CATransaction.setCompletionBlock{ [weak self] in 
     self?.animeExample() 
    } 

    someLayer.add(a, forKey: nil) 
    CATransaction.commit() 
} 

在這個例子中,它只是再次調用自己。

當然,你可以調用任何函數。


注意:如果你剛開始。值得記住的是,「鑰匙」(如add#forKey)是不相關的,很少使用。將其設置爲零。如果由於某種原因你想設置它,它是「任何字符串」(比如你的暱稱)。 CABasicAnimation調用中的keyPath是實際的「你正在動畫的東西」,換句話說,它實際上是圖層的一個屬性(只是寫成一個字符串)。

1

斯威夫特4+我剛纔說delegate

class CircleView: UIView,CAAnimationDelegate { 
... 

let animation = CABasicAnimation(keyPath: "strokeEnd") 
animation.delegate = self//Set delegate 

動畫完成回調 -

func animationDidStop(_ anim: CAAnimation, finished flag: Bool) { 
    print("Animation END") 
    }