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,即:
-
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
。 -
value
属性正在调用layoutSubviews
:var value: Int? { didSet { progress(value: value!) self.layoutSubviews() } }
切勿直接调用
layoutSubviews()
。 -
视图控制器正在执行以下操作:
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
执行此操作在视图生命周期中通常为时尚早。 -
与
viewDidLoad
代码相关的是,在将视图添加到视图层次结构之前,您正在更改DetailView
(它触发了animation)的value
。