如何从我的 UIView 中删除 CAShapeLayer 和 CABasicAnimation?

How do I remove a CAShapeLayer and CABasicAnimation from my UIView?

这是我的代码:

@objc func drawForm() {
    i = Int(arc4random_uniform(UInt32(formNames.count)))
    var drawPath = actualFormNamesFromFormClass[i]
    shapeLayer.fillColor = UIColor.clear.cgColor
    shapeLayer.strokeColor = UIColor.black.cgColor
    shapeLayer.lineWidth = 6
    shapeLayer.frame = CGRect(x: -115, y: 280, width: 350, height: 350)

    var paths: [UIBezierPath] = drawPath()
    let shapeBounds = shapeLayer.bounds
    let mirror = CGAffineTransform(scaleX: 1,
                                   y: -1)
    let translate = CGAffineTransform(translationX: 0,
                                      y: shapeBounds.size.height)
    let concatenated = mirror.concatenating(translate)

    for path in paths {
        path.apply(concatenated)
    }

    guard let path = paths.first else {
        return
    }

    paths.dropFirst()
        .forEach {
            path.append([=10=])
    }

    shapeLayer.transform = CATransform3DMakeScale(0.6, 0.6, 0)
    shapeLayer.path = path.cgPath

    self.view.layer.addSublayer(shapeLayer)

    strokeEndAnimation.duration = 30.0
    strokeEndAnimation.fromValue = 0.0
    strokeEndAnimation.toValue = 1.0
    shapeLayer.add(strokeEndAnimation, forKey: nil)
}

此代码为 shapeLayer 路径的绘制设置动画,但是我无法在网上找到任何有关删除此层并停止此基本动画或删除绘制的 cgPath 的信息...任何帮助将不胜感激!

您可以使用动画委托 CAAnimationDelegate 在动画开始或结束时执行附加逻辑。例如,您可能希望在淡出动画完成后从其父层移除一个层。

下面的代码取自 class,它在图层上实现了 CAAnimationDelegate,当您调用 fadeOut 函数时会对该图层的不透明度进行动画处理,一旦动画完成,animationDidStop(_:finished:) 将其从其超层中移除。

extension CALayer : CAAnimationDelegate  {
    func fadeOut() {
        let fadeOutAnimation = CABasicAnimation()
        fadeOutAnimation.keyPath = "opacity"
        fadeOutAnimation.fromValue = 1
        fadeOutAnimation.toValue = 0
        fadeOutAnimation.duration = 0.25
        fadeOutAnimation.delegate = self
        self.add(fadeOutAnimation,
                     forKey: "fade")
    }

    public func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
        self.removeFromSuperlayer()
    }
}

你说:

I can't find anything online about removing this layer ...

removeFromSuperlayer().

shapeLayer.removeFromSuperlayer()

你接着说:

... and stopping this basic animation ...

removeAllAnimations:

shapeLayer.removeAllAnimations()

请注意,这会立即将 strokeEnd(或任何您正在设置动画的 属性)改回其先前的值。如果你想 "freeze" 它在你停止它的地方,你必须抓住 presentation 层(它捕获层的属性,因为它们是 mid-animation),保存适当的 属性 ,然后更新要停止动画的层的 属性:

if let strokeEnd = shapeLayer.presentation()?.strokeEnd {
    shapeLayer.removeAllAnimations()
    shapeLayer.strokeEnd = strokeEnd
}

最后,你接着说:

... or removing the cgPath that gets drawn.

只需设置为nil:

shapeLayer.path = nil

顺便说一下,当您分别浏览 CAShapeLayer and CABasicAnimation, don't forget to check out the documentation for their superclasses, namely and CALayer and CAAnimation » CAPropertyAnimation 的文档时。底线是,当四处寻找有关某些特定 class 的属性或方法的文档时,您通常必须深入研究超级 classes 才能找到相关信息。

最后,Core Animation Programming Guide 是一个很好的介绍,虽然它的示例在 Objective-C 中,但所有概念都适用于 Swift。