2008-11-17 63 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") 
    }