Я пытаюсь создать круговой индикатор выполнения в Swift 4, используя CAShapeLayer
и анимированный UIBezierPath
.Это работает нормально, но я бы хотел, чтобы круг изменил значение strokeColor
, как только анимация достигнет определенного значения.
Например: когда круг нарисован на 75%, я хочу переключить strokeColor
с UIColor.black.cgColor
to UIColor.red.cgColor
.
Мой код для круга и анимации «Прогресс» выглядит следующим образом:
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")
Я знаю, что также возможно создать CABasicAnimation
дляstrokeColor
keypath и установите fromValue
и toValue
на UIColors
, чтобы strokeColor
медленно изменялся.Но это похоже на переход во времени, который не совсем то, что я хочу.
Обновление 1:
Основываясь на ответе Михая Фрату, я смог решить свою проблему.Для дальнейшего использования я хочу добавить минимальный 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")