我正在制作 iOS App 。我有几个CALayer
个对象,最终将被<缩小的动画 删除。完成动画并调用animationDidStop:finished
后,我想从超级视图中删除 CALayer
对象并将其删除。
CALayer
个对象
animationDidStop:finished
?我猜对了
CAanimation
- 对象有一个指向图层的指针,但我找不到它
在文档中。 答案 0 :(得分:5)
回答这个问题已有很长时间了,但是,如果今天仍然有人在寻找更干净的解决方案,我将尝试添加更多的迅速解决方案。
如果您感兴趣的一切只是在CAAnimation完成后立即删除该层,则可以将动画的委托分配给一个简单的NSObject,该对象包含对目标层的引用并等待动画回调以便消除它。
我们将此助手对象称为 LayerRemover :
class LayerRemover: NSObject, CAAnimationDelegate {
private weak var layer: CALayer?
init(for layer: CALayer) {
self.layer = layer
super.init()
}
func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
layer?.removeFromSuperlayer()
}
}
该对象所做的所有事情都是通过初始化程序接收CALayer引用,并在删除图层之前等待animationDidStop回调。此时,一旦通过委托属性保留它的CAAnimation被取消初始化,Layer remover也将被清除。
现在,您所要做的实际上是使该卸妆剂无效并使用它:
let layer = CAShapeLayer()
layer.path = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: 200, height: 100)).cgPath
let myAnimation = CABasicAnimation(keyPath: "strokeEnd")
...
myAnimation.delegate = LayerRemover(for: layer)
就是这样!
请注意,您不必保留对LayerRemover对象的任何引用,因为从Apple documentation中我们可以读取
委托对象由接收者保留。这是“高级内存管理编程指南”中所述的内存管理规则的罕见例外。
答案 1 :(得分:1)
创建动画并设置委托时,只需使用动画传递要删除的CALayer。
至于删除所有动画,您有两种选择:
答案 2 :(得分:0)
看看这个答案是否有帮助:Perform an action after the animation has finished我发现animateWithDuration:动画:完成:比直接使用CALayer更容易使用。您可以通过完成处理程序链接多个动画,然后删除最后一个中的图层。例如:
[UIView animateWithDuration:1.0 animations:^{
// do first animation in the sequence
} completion:^(BOOL finished) {
[UIView animateWithDuration:1.0 animations:^{
// do second animation in the sequence
} completion:^(BOOL finished) {
[UIView animateWithDuration:1.0 animations:^{
// do third animation in the sequence
} completion:^(BOOL finished) {
// remove layer after all are done
}];
}];
}];
这种方式可能有点乱,但你可以将它们重构为自己的方法调用,例如。
答案 3 :(得分:0)
一种替代解决方案是将一个图层指针添加到动画对象的字典中,如下所示
// in some define section
#define kAnimationRemoveLayer @"animationRemoveLayer"
然后,在animationDidStop中,
- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag{
CALayer *lay = [theAnimation valueForKey:kAnimationRemoveLayer];
if(lay){
[lay removeAllAnimations];
[lay removeFromSuperlayer];
}
}
,最后,在动画设置中,
CALAyer * lay = ... ; BOOL shouldRemove = .... ; CABasicAnimation* anim = [CABasicAnimation animationWithKeyPath:@"position"]; anim.delegate = self; if (shouldRemove) [anim setValue:lay forKey:kAnimationRemoveLayer];