我想知道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。
使用.setCompletionBlock
在实践中你需要[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
)是无关紧要的,很少使用。设置为零。如果由于某种原因您想要设置它,请将其设置为“任何字符串”(例如,您的昵称)。另一方面...keyPath
调用中的CABasicAnimation
实际上是实际的“你正在动画的东西”,换句话说,它实际上是图层的属性(但只是写成一个字符串)。总之,add#forKey
几乎总是零,这是无关紧要的。它与“keyPath”完全无关 - 事实上,他们在名称中都有“关键”是纯属巧合,这两件事完全无关。
你经常看到这两个混淆的代码(感谢愚蠢的命名),这会导致各种各样的问题。
请注意,截至最近您可以使用animationDidStop
与代表,请参阅@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")
}
Swift 5.0
func blinkShadow(completion: @escaping (() -> Void)) {
CATransaction.begin()
let animation = CABasicAnimation(keyPath: "shadowRadius")
animation.fromValue = layer.shadowRadius
animation.toValue = 0.0
animation.duration = 0.1
animation.autoreverses = true
CATransaction.setCompletionBlock(completion)
layer.add(animation, forKey: nil)
CATransaction.commit()
}
您可以在设置CAAnimation对象时设置给定动画的名称。在animationDiStop中:完成后,只需比较提供的动画对象的名称,即可根据动画执行特定功能。