在特定点更改动画 UIBezierPath 的颜色
Change Color of an Animated UIBezierPath at a Certain Point
我正在尝试使用 CAShapeLayer
和动画 UIBezierPath
在 Swift 4 中创建一个圆形进度条。这工作正常,但我希望圆圈在动画达到某个值后将其更改为 strokeColor
。
例如:一旦圆绘制了 75%,我想将 strokeColor
从 UIColor.black.cgColor
切换到 UIColor.red.cgColor
。
我的圆圈代码和 "progress" 动画如下所示:
let circleLayer = CAShapeLayer()
// set initial strokeColor:
circleLayer.strokeColor = UIColor.black.cgColor
circleLayer.path = UIBezierPath([...]).cgPath
// animate the circle:
let animation = CABasicAnimation()
animation.keyPath = #keyPath(CAShapeLayer.strokeEnd)
animation.fromValue = 0.0
animation.toValue = 1
animation.duration = 10
animation.isAdditive = true
animation.fillMode = .forwards
circleLayer.add(animation, forKey: "strokeEnd")
我知道也可以为 strokeColor
键路径创建一个 CABasicAnimation
并将 fromValue
和 toValue
设置为 UIColors
以获得strokeColor
要慢慢改。但这就像随着时间的推移而发生的转变,这并不是我想要的。
更新 1:
根据 Mihai Fratu 的回答,我解决了我的问题。为了将来参考,我想添加一个最小的 Swift 4 代码示例:
// Create the layer with the circle path (UIBezierPath)
let circlePathLayer = CAShapeLayer()
circlePathLayer.path = UIBezierPath([...]).cgPath
circlePathLayer.strokeEnd = 0.0
circlePathLayer.strokeColor = UIColor.black.cgColor
circlePathLayer.fillColor = UIColor.clear.cgColor
self.layer.addSublayer(circlePathLayer)
// Create animation to animate the progress (circle slowly draws)
let progressAnimation = CABasicAnimation()
progressAnimation.keyPath = #keyPath(CAShapeLayer.strokeEnd)
progressAnimation.fromValue = 0.0
progressAnimation.toValue = 1
// Create animation to change the color
let colorAnimation = CABasicAnimation()
colorAnimation.keyPath = #keyPath(CAShapeLayer.strokeColor)
colorAnimation.fromValue = UIColor.black.cgColor
colorAnimation.toValue = UIColor.red.cgColor
colorAnimation.beginTime = 3.75 // Since your total animation is 10s long, 75% is 7.5s - play with this if you need something else
colorAnimation.duration = 0.001 // make this really small - this way you "hide" the transition
colorAnimation.fillMode = .forwards
// Group animations together
let progressAndColorAnimation = CAAnimationGroup()
progressAndColorAnimation.animations = [progressAnimation, colorAnimation]
progressAndColorAnimation.duration = 5
// Add animations to the layer
circlePathLayer.add(progressAndColorAnimation, forKey: "strokeEndAndColor")
如果我正确理解了您的问题,那么这应该可以满足您的需求。请记住,它根本没有经过测试:
let circleLayer = CAShapeLayer()
// set initial strokeColor:
circleLayer.strokeColor = UIColor.black.cgColor
circleLayer.path = UIBezierPath([...]).cgPath
// animate the circle:
let animation = CABasicAnimation()
animation.keyPath = #keyPath(CAShapeLayer.strokeEnd)
animation.fromValue = 0.0
animation.toValue = 1
animation.beginTime = 0 // Being part of an animation group this is relative to the animation group start time
animation.duration = 10
animation.isAdditive = true
animation.fillMode = .forwards
// animate the circle color:
let colorAnimation = CABasicAnimation()
colorAnimation.keyPath = #keyPath(CAShapeLayer.strokeColor)
colorAnimation.fromValue = UIColor.black.cgColor
colorAnimation.toValue = UIColor.black.red
colorAnimation.beginTime = 7.5 // Since your total animation is 10s long, 75% is 7.5s - play with this if you need something else
colorAnimation.duration = 0.0001 // make this really small - this way you "hide" the transition
colorAnimation.isAdditive = true
colorAnimation.fillMode = .forwards
let sizeAndColorAnimation = CAAnimationGroup()
sizeAndColorAnimation.animations = [animation, colorAnimation]
sizeAndColorAnimation.duration = 10
circleLayer.add(sizeAndColorAnimation, forKey: "strokeEndAndColor")
我正在尝试使用 CAShapeLayer
和动画 UIBezierPath
在 Swift 4 中创建一个圆形进度条。这工作正常,但我希望圆圈在动画达到某个值后将其更改为 strokeColor
。
例如:一旦圆绘制了 75%,我想将 strokeColor
从 UIColor.black.cgColor
切换到 UIColor.red.cgColor
。
我的圆圈代码和 "progress" 动画如下所示:
let circleLayer = CAShapeLayer()
// set initial strokeColor:
circleLayer.strokeColor = UIColor.black.cgColor
circleLayer.path = UIBezierPath([...]).cgPath
// animate the circle:
let animation = CABasicAnimation()
animation.keyPath = #keyPath(CAShapeLayer.strokeEnd)
animation.fromValue = 0.0
animation.toValue = 1
animation.duration = 10
animation.isAdditive = true
animation.fillMode = .forwards
circleLayer.add(animation, forKey: "strokeEnd")
我知道也可以为 strokeColor
键路径创建一个 CABasicAnimation
并将 fromValue
和 toValue
设置为 UIColors
以获得strokeColor
要慢慢改。但这就像随着时间的推移而发生的转变,这并不是我想要的。
更新 1:
根据 Mihai Fratu 的回答,我解决了我的问题。为了将来参考,我想添加一个最小的 Swift 4 代码示例:
// Create the layer with the circle path (UIBezierPath)
let circlePathLayer = CAShapeLayer()
circlePathLayer.path = UIBezierPath([...]).cgPath
circlePathLayer.strokeEnd = 0.0
circlePathLayer.strokeColor = UIColor.black.cgColor
circlePathLayer.fillColor = UIColor.clear.cgColor
self.layer.addSublayer(circlePathLayer)
// Create animation to animate the progress (circle slowly draws)
let progressAnimation = CABasicAnimation()
progressAnimation.keyPath = #keyPath(CAShapeLayer.strokeEnd)
progressAnimation.fromValue = 0.0
progressAnimation.toValue = 1
// Create animation to change the color
let colorAnimation = CABasicAnimation()
colorAnimation.keyPath = #keyPath(CAShapeLayer.strokeColor)
colorAnimation.fromValue = UIColor.black.cgColor
colorAnimation.toValue = UIColor.red.cgColor
colorAnimation.beginTime = 3.75 // Since your total animation is 10s long, 75% is 7.5s - play with this if you need something else
colorAnimation.duration = 0.001 // make this really small - this way you "hide" the transition
colorAnimation.fillMode = .forwards
// Group animations together
let progressAndColorAnimation = CAAnimationGroup()
progressAndColorAnimation.animations = [progressAnimation, colorAnimation]
progressAndColorAnimation.duration = 5
// Add animations to the layer
circlePathLayer.add(progressAndColorAnimation, forKey: "strokeEndAndColor")
如果我正确理解了您的问题,那么这应该可以满足您的需求。请记住,它根本没有经过测试:
let circleLayer = CAShapeLayer()
// set initial strokeColor:
circleLayer.strokeColor = UIColor.black.cgColor
circleLayer.path = UIBezierPath([...]).cgPath
// animate the circle:
let animation = CABasicAnimation()
animation.keyPath = #keyPath(CAShapeLayer.strokeEnd)
animation.fromValue = 0.0
animation.toValue = 1
animation.beginTime = 0 // Being part of an animation group this is relative to the animation group start time
animation.duration = 10
animation.isAdditive = true
animation.fillMode = .forwards
// animate the circle color:
let colorAnimation = CABasicAnimation()
colorAnimation.keyPath = #keyPath(CAShapeLayer.strokeColor)
colorAnimation.fromValue = UIColor.black.cgColor
colorAnimation.toValue = UIColor.black.red
colorAnimation.beginTime = 7.5 // Since your total animation is 10s long, 75% is 7.5s - play with this if you need something else
colorAnimation.duration = 0.0001 // make this really small - this way you "hide" the transition
colorAnimation.isAdditive = true
colorAnimation.fillMode = .forwards
let sizeAndColorAnimation = CAAnimationGroup()
sizeAndColorAnimation.animations = [animation, colorAnimation]
sizeAndColorAnimation.duration = 10
circleLayer.add(sizeAndColorAnimation, forKey: "strokeEndAndColor")