Animar propiedad personalizada de UIView en Swift
¡todas!
He creado una vista de progreso circular usandoCoreGraphics
que se ve y actualiza así:
La clase es unUIView
clase, y tiene una variable llamada 'progreso' que determina cuánto del círculo se llena.
Funciona bien, pero quiero poder animar los cambios en la variable de progreso para que la barra se anime sin problemas.
He leído de innumerables ejemplos que necesito tener unCALayer
clase junto con la clase View, que he realizado, sin embargo, no se anima en absoluto.
Dos preguntas:
¿Puedo mantener el gráfico que dibujé?CoreGraphics
o necesito volver a dibujarlo de alguna maneraCALayer
?Mi solución actual (intentada) se bloquea hacia abajo en:anim.fromValue = pres.progress
. ¿Qué pasa?
class CircleProgressView: UIView {
@IBInspectable var backFillColor: UIColor = UIColor.blueColor()
@IBInspectable var fillColor: UIColor = UIColor.greenColor()
@IBInspectable var strokeColor: UIColor = UIColor.greenColor()
dynamic var progress: CGFloat = 0.00 {
didSet {
self.layer.setValue(progress, forKey: "progress")
}
}
var distToDestination: CGFloat = 10.0
@IBInspectable var arcWidth: CGFloat = 20
@IBInspectable var outlineWidth: CGFloat = 5
override class func layerClass() -> AnyClass {
return CircleProgressLayer.self
}
override func drawRect(rect: CGRect) {
var fillColor = self.fillColor
if distToDestination < 3.0 {
fillColor = UIColor.greenColor()
} else {
fillColor = self.fillColor
}
//Drawing the inside of the container
//Drawing in the container
let center = CGPoint(x:bounds.width/2, y: bounds.height/2)
let radius: CGFloat = max(bounds.width, bounds.height) - 10
let startAngle: CGFloat = 3 * π / 2
let endAngle: CGFloat = 3 * π / 2 + 2 * π
let path = UIBezierPath(arcCenter: center, radius: radius/2 - arcWidth/2, startAngle: startAngle, endAngle: endAngle, clockwise: true)
path.lineWidth = arcWidth
backFillColor.setStroke()
path.stroke()
let fill = UIColor.blueColor().colorWithAlphaComponent(0.15)
fill.setFill()
path.fill()
//Drawing the fill path. Same process
let fillAngleLength = (π) * progress
let fillStartAngle = 3 * π / 2 - fillAngleLength
let fillEndAngle = 3 * π / 2 + fillAngleLength
let fillPath_fill = UIBezierPath(arcCenter: center, radius: radius/2 - arcWidth/2, startAngle: fillStartAngle, endAngle: fillEndAngle, clockwise: true)
fillPath_fill.lineWidth = arcWidth
fillColor.setStroke()
fillPath_fill.stroke()
//Drawing container outline on top
let outlinePath_outer = UIBezierPath(arcCenter: center, radius: radius / 2 - outlineWidth / 2, startAngle: startAngle, endAngle: endAngle, clockwise: true)
let outlinePath_inner = UIBezierPath(arcCenter: center, radius: radius / 2 - arcWidth + outlineWidth / 2, startAngle: startAngle, endAngle: endAngle, clockwise: true)
outlinePath_outer.lineWidth = outlineWidth
outlinePath_inner.lineWidth = outlineWidth
strokeColor.setStroke()
outlinePath_outer.stroke()
outlinePath_inner.stroke()
}
}
class CircleProgressLayer: CALayer {
@NSManaged var progress: CGFloat
override class func needsDisplayForKey(key: String) -> Bool {
if key == "progress" {
return true
}
return super.needsDisplayForKey(key)
}
override func actionForKey(key: String) -> CAAction? {
if (key == "progress") {
if let pres = self.presentationLayer() {
let anim: CABasicAnimation = CABasicAnimation.init(keyPath: key)
anim.fromValue = pres.progress
anim.duration = 0.2
return anim
}
return super.actionForKey(key)
} else {
return super.actionForKey(key)
}
}
}
¡Gracias por la ayuda!