我想知道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.
你可以使用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];
我回答了自己的问题.您必须使用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
用这种垃圾浪费了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];
以下是基于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()
斯威夫特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下面的答案!在某些情况下,这更容易; 有时候使用完成块会更容易.如果您有许多不同的动画(通常是这种情况),只需使用完成块.
对于那些在Google上找到此页面的人来说,这只是一个注意事项:您真的可以通过将动画对象的"委托"属性设置为将接收通知的对象并在该对象的.m中实现"animationDidStop"方法来完成工作.文件.我刚尝试过,它的确有效.我不知道为什么Joe Blow说这不是正确的方法.
在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") }