为啥我的 CAShapeLayer 没有动画? (iOS 斯威夫特)

Posted

技术标签:

【中文标题】为啥我的 CAShapeLayer 没有动画? (iOS 斯威夫特)【英文标题】:Why is my CAShapeLayer not animating? (iOS Swift)为什么我的 CAShapeLayer 没有动画? (iOS 斯威夫特) 【发布时间】:2015-04-05 17:33:18 【问题描述】:

在我的一个 ViewControllers 中,我的 addStatus() 粘贴在下面的 viewDidLoad 中。我希望这个圈子的lineWidth 能够动画化,但它似乎没有这样做。在我寻找这可能的原因时,我在Animating Layer Content 上找到了 Apple 文档的这一部分。我认为重要的部分在这里注明:

如果您想使用 Core Animation 类来启动动画,您必须从基于视图的动画块内发出所有 Core Animation 调用。 UIView 类默认禁用图层动画,但在动画块内重新启用它们。因此,您在动画块之外所做的任何更改都不是动画。清单 3-5 展示了如何隐式更改图层的不透明度和显式更改其位置的示例。在此示例中,myNewPosition 变量是预先计算并由块捕获的。两个动画同时开始,但不透明动画以默认时间运行,而位置动画以其动画对象中指定的时间运行。

当我查找为什么这可能不是动画时,我阅读了这篇文章并认为这意味着我应该将我的 CAAnimation 放在 UIView 动画块中。当放置在rootViewController 中时,此功能在没有动画块的空白应用程序中运行良好,但在我的辅助viewController 中时似乎没有动画。任何提示都会非常有帮助。谢谢!

func addStatus() 

        UIView.animateWithDuration( NSTimeInterval.infinity, animations:  () -> Void in

            let patientZeroIndicator = CAShapeLayer()

            let radius:CGFloat = 20.0
            let center:CGPoint = CGPointMake(self.view.frame.width - radius - 10, radius + 10)
            let startAngle = 0.0
            let endAngle = 2.0 * Double(M_PI)

            patientZeroIndicator.lineWidth = 10.0
            patientZeroIndicator.fillColor = UIColor(netHex: cs_red).CGColor
            patientZeroIndicator.strokeColor = UIColor.whiteColor().CGColor
            patientZeroIndicator.path = UIBezierPath(arcCenter: center, radius: radius, startAngle: CGFloat(startAngle), endAngle: CGFloat(endAngle), clockwise: true).CGPath
            self.view.layer.addSublayer(patientZeroIndicator)

            // Create a blank animation using the keyPath "cornerRadius", the property we want to animate
            let pZeroAnimation = CABasicAnimation(keyPath: "lineWidth")

            // Define the parameters for the tween
            pZeroAnimation.fromValue = 10.0
            pZeroAnimation.toValue = 5.0
            pZeroAnimation.autoreverses  = true
            pZeroAnimation.duration = 3.0
            pZeroAnimation.repeatDuration = CFTimeInterval.infinity
            pZeroAnimation.timingFunction = CAMediaTimingFunction(controlPoints: 0.25, 0, 0.75, 1)

            // Finally, add the animation to the layer
            patientZeroIndicator.addAnimation(pZeroAnimation, forKey: "lineWidth")
        )
    

【问题讨论】:

对于任何在这里使用谷歌搜索的人,我会敦促您将视图子类化。这比尝试从视图控制器执行此操作要简单、容易和快速得多。网上很多例子...***.com/a/58681566/294884 【参考方案1】:

在我的viewDidLoad

那是你的问题。 viewDidLoad 方法在视图添加到窗口之前运行。除非它在窗口中,否则您不能将动画添加到视图中。改为在viewDidAppear: 中调用addStatus

另外,不要在动画块中创建新图层。在viewDidLoad 中创建图层。

【讨论】:

谢谢 Rob,就是这样。很清楚的解释。

以上是关于为啥我的 CAShapeLayer 没有动画? (iOS 斯威夫特)的主要内容,如果未能解决你的问题,请参考以下文章

CAShapeLayer 动画的完成块

如何使用 CAShapeLayer 使我的 UIBezierPath 动画?

CAShapeLayer的缩放动画问题[重复]

CAShapeLayer 动画无需更新路径

CAShapeLayer 路径动画

CAShapeLayer 动画路径毛刺/闪烁(从椭圆到矩形并返回)