CAShapeLayer上的CABasicAnimation不能用于path更改

我在这里有一个进度方法:

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 } } 

我正在尝试以animation方式进度栏进度。 但是当我打电话progress(100) ,只是简单的渲染吧,没有animation。

我该如何解决?

更新 :根据Rob的build议创build了MCVE: https : //github.com/utkarsh2012/ProgressBarTest 。 我期望进度条从宽度= 0到宽度= x(比如说60)

看起来类似于这个问题与CALayerpathCABasicAnimation不animation

最初在你的问题中显示的progress方法是好的。 问题在于你如何使用它。 刚才已经说过了,我们来看看MCVE。

在你的MCVE中 ,有几件事阻止了animation,即:

  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) } } 

    这就是将path设置为新的path,然后从那个path开始animation到新path(即从同一path进行animation)。 因此,没有animation。

    在将path更改为新的“结束状态”并启动animation之前保存旧path。 使用该保存的path作为animation的fromValue

  2. value属性正在调用layoutSubviews

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

    切勿直接调用layoutSubviews()

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

     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启动animation。 在视图生命周期中,这太早了。 使用viewDidAppear (或其他)。 在viewDidLoad执行此操作在视图生命周期中通常为时尚早。

  4. viewDidLoad代码相关的是,在将视图添加到视图层次结构之前,您正在更改DetailView (它触发了animation)的value


看到这里修复https://github.com/robertmryan/ProgressBarTest