CAShapeLayer上的CABasicAnimation无法用于路径更改 [英] CABasicAnimation on CAShapeLayer not working for path change

查看:140
本文介绍了CAShapeLayer上的CABasicAnimation无法用于路径更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个进度方法此处

func progress(incremented : CGFloat){
    if incremented <= self.bounds.width{
        self.progressLayer.removeFromSuperlayer()
        let originBezierPathProg = UIBezierPath(roundedRect: CGRect(x:0, y:0, width:0, height:self.bounds.height) , cornerRadius: self.viewCornerRadius)
        originBezierPathProg.close()

        let newBezierPathProg = UIBezierPath(roundedRect: CGRect(x:0, y:0, width:incremented, height:self.bounds.height) , cornerRadius: self.viewCornerRadius)
        bezierPathProg.close()

        self.progressLayer.path = originBezierPathProg.cgPath
        self.borderLayer.addSublayer(self.progressLayer)

        let animation = CABasicAnimation(keyPath: "path")
        animation.fromValue = originBezierPathProg.cgPath
        animation.toValue = newBezierPathProg.cgPath
        animation.duration = 1
        self.progressLayer.add(animation, forKey: animation.keyPath)

        self.progressLayer.path = newBezierPathProg.cgPath
    }
}

我正在尝试制作进度条以动画方式显示进度。但是当我调用 progress(100)时,它只是在没有动画的情况下渲染了条形图。

I am trying to make progress bar progress in an animated way. But when I call progress(100), it's simply rendering the bar without animation.

如何修复它?

更新:根据Rob的建议创建了MCVE: https://github.com/utkarsh2012/ProgressBarTest 。我希望进度条从width = 0到width = x进行动画处理(例如60)

Update: Created MCVE as per Rob's suggestion: https://github.com/utkarsh2012/ProgressBarTest . I expect the progress bar to animate from width=0 to width=x (say 60)

看起来类似于此问题使用CALayer路径的CABasicAnimation无法设置动画

推荐答案

问题中最初显示的进度方法很好。问题在于您如何使用它。话虽如此,让我们看一下MCVE。

The progress method originally shown in your question is fine. The problem is in how you used it. That having been said, let's go through the MCVE.

您的MCVE ,有一些阻止动画的内容,即:

In your MCVE, there were a few things preventing the animation, namely:


  1. progress 方法如下:

func progress(incremented: CGFloat) {
    if incremented <= bounds.width {
        let toPath = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: incremented + 100, height: bounds.height), cornerRadius: viewCornerRadius)

        progressLayer.path = toPath.cgPath
        borderLayer.addSublayer(progressLayer)

        let animation = CABasicAnimation(keyPath: "path")
        animation.fromValue = self.progressLayer.path
        animation.toValue = toPath.cgPath
        animation.duration = 3
        progressLayer.add(animation, forKey: animation.keyPath)
    }
}

这是将路径设置为新路径,然后从该路径动画到新路径(即动画与同一路径之间的动画)。因此,没有动画。

That is setting the path to be the new path, and then animating from that to the new path (i.e. animating to and from the same path). Thus, no animation.

在将路径更改为其新的结束状态并启动动画之前,请保存旧路径。将保存的路径用作动画的 fromValue

Save the old path before changing the path to its new "end state" and initiating the animation. Use that saved path as the fromValue of the animation.

属性正在调用 layoutSubviews

var value: Int? {
    didSet {
        progress(value: value!)
        self.layoutSubviews()
    }
}

从不直接调用 layoutSubviews()

视图控制器正在执行以下操作:

The view controller was doing the following:

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    let view = DetailView(frame: self.view.frame)
    view.value = 60
    self.containerView.addSubview(view)
}

不要尝试在 viewDidLoad 中启动动画。在视图生命周期中还为时过早。改用 viewDidAppear (或其他)。在 viewDidLoad 中执行此操作通常在视图生命周期中为时过早。

Don't try to start animations in viewDidLoad. That's too early in the view lifecycle. Use viewDidAppear (or whatever) instead. Doing this in viewDidLoad is generally too early in the view lifecycle.

与该<$ c有关$ c> viewDidLoad 代码,您正在更改 DetailView (已触发动画)),然后再将其添加到视图层次结构中。

Related to that viewDidLoad code, you were changing the value of the DetailView (which triggered the animation) before you've added it to the view hierarchy.






在此处查看修复程序 https://github.com/robertmryan/ProgressBarTest

这篇关于CAShapeLayer上的CABasicAnimation无法用于路径更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆