Animate Custom UIView-Eigenschaft in Swift

alle

Ich habe eine zirkuläre Fortschrittsanzeige mit @ erstellCoreGraphics das sieht so aus und aktualisiert sich so:

50% 75%

Die Klasse ist einUIView Klasse, und es hat eine Variable namens "Fortschritt", die bestimmt, wie viel des Kreises ausgefüllt ist.

Es funktioniert gut, aber ich möchte Änderungen an der Fortschrittsvariablen animieren können, damit die Leiste reibungslos animiert wird.

Ich habe aus unzähligen Beispielen gelesen, dass ich ein @ haben muCALayer class zusammen mit der View-Klasse, die ich erstellt habe, wird jedoch überhaupt nicht animiert.

Zwei Fragen

ann ich die Grafik, die ich gezeichnet habe, behalteCoreGraphics, oder muss ich es irgendwie in @ neu zeichnCALayer?

Meine aktuelle (versuchte) Lösung stürzt nach unten ab bei:anim.fromValue = pres.progress. Was geht

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

Danke für die Hilfe

Antworten auf die Frage(4)

Ihre Antwort auf die Frage