当前位置:  开发笔记 > 编程语言 > 正文

CALayer的动画结束回调?

如何解决《CALayer的动画结束回调?》经验,为你挑选了7个好方法。

我想知道CALayer中动画的回调位置(或者有什么内容).具体来说,对于隐含的动画,如改变框架,位置等.在UIView中,你可以这样做:

[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.



1> bennythemink..:

你可以使用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];


请注意,在将动画添加到图层之前设置完成块非常重要.

2> Jeffrey Forb..:

我回答了自己的问题.您必须使用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


这个答案对于有关委托的信息很有用,但它有一个很大的缺陷 - 你不能为"框架"设置动画,因为它是派生属性.http://developer.apple.com/library/mac/#qa/qa2008/qa1620.html

3> user3077725..:

用这种垃圾浪费了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];



4> tdon..:

以下是基于bennythemink解决方案的Swift 3.0中的答案:

    // 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() 



5> 小智..:
2018年......

斯威夫特4.

使用 [weak self]

在实践中,你需要forKey或者你通常会崩溃.

func animeExample() {

    CATransaction.begin()

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

    CATransaction.setCompletionBlock{ [weak self] in
        self?.animeExample()
        self?.ringBell()
        print("again...")
    }

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

在这个例子中,它只是再次调用自己.

当然,你可以调用任何函数.


注意:如果你刚开始.值得记住的

    "密钥"(如在[weak self])中是无关紧要的,很少使用.设置为零.如果由于某种原因您想要设置它,请将其设置为"任何字符串"(例如,您的昵称).另一方面...

    forKey[weak self]调用实际上是在实际的"你是动画的事情",换句话说,它的字面层的属性(但只是作为字符串写入).

总之forKey,几乎总是只有零,这是无关紧要的.它与"keyPath"完全无关 - 事实上,他们在名称中都有"关键"是纯属巧合,这两件事完全无关.

你经常看到这两个混淆的代码(感谢愚蠢的命名),这会导致各种各样的问题.


请注意,截至最近您可以[weak self]与代表一起使用,请参阅@jack下面的答案!在某些情况下,这更容易; 有时候使用完成块会更容易.如果您有许多不同的动画(通常是这种情况),只需使用完成块.



6> moonman239..:

对于那些在Google上找到此页面的人来说,这只是一个注意事项:您真的可以通过将动画对象的"委托"属性设置为将接收通知的对象并在该对象的.m中实现"animationDidStop"方法来完成工作.文件.我刚尝试过,它的确有效.我不知道为什么Joe Blow说这不是正确的方法.



7> Jack..:

Swift 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")
  }

推荐阅读
落单鸟人
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有