Implicit CALayer animations for a custom property in Swift

I created an animated drawing of Core Graphics using PaintCode. This is basically a circle meter (not like Apple Watch rings) that basically fills up when the timer counts down. The measurement of the light level controls the fill level of the circle meter from 0 to 100. In principle, if the timer is set for 10 seconds, I set the measuring level every 1 s to 90, 80, 70, etc.

This works well, however the animation is only drawn for just 1 second and looks pretty choppy. Instead, I would like it to be a smooth continuous fill meter.

Looking around, it seemed that subclassing CALayer and creating an implicit animation for the meterLevel property could be a way. So here is what I have:

import UIKit

class MeterControlView: UIView
{
var meterLevel: Int = 0 {
    didSet {
        self.layer.setValue(meterLevel, forKey: "meterLevel")
    }
}
var meterText: String = "00:00:00" {
    didSet {
        self.layer.setValue(meterText, forKey: "meterText")
    }
}


override class func layerClass() -> AnyClass {
    return MeterControlLayer.self
}

override func drawRect(rect: CGRect) {
    // Do nothing
    }
}

class MeterControlLayer: CALayer
{
@NSManaged
var meterLevel: Int
var meterText: String = "00:00:00"

override class func needsDisplayForKey(key: String) -> Bool {
    if (key == "meterLevel") {
        return true
    }
    return super.needsDisplayForKey(key)
}

override func actionForKey(key: String) -> CAAction? {
    if (key == "meterLevel") {
        let anim: CABasicAnimation = CABasicAnimation.init(keyPath: key)
        anim.fromValue = self.presentationLayer()?.meterLevel
        anim.duration = 1.0
        return anim
    } else {
        return super.actionForKey(key)
    }
}

override func drawInContext(ctx: CGContext) {
    super.drawInContext(ctx)
    UIGraphicsPushContext(ctx)
    XntervalStyleKit.drawMeterControl(frame: self.bounds, meterTime: meterText, meterLevelValue: CGFloat(meterLevel))
    UIGraphicsPopContext()
    }
}

, , , . - , , .

, , , ? meterLevel meterText, setValueForKey:. ?

/ . , C, iOS .

+4
2

- , , .

, , Core Animation ( ).

, , : , Core Animation (, ), , . , , .

drawInContext(_:), , . , ? , . , .

drawsAsynchronously true . , . ( , , , UIGraphics Core Graphics iOS 4, .)

, , , ( , ). - , , , .

+1

UIView ConcentricProgressRingView, - , .

https://github.com/lionheart/ConcentricProgressRingView

, :

UIViewController :

import ConcentricProgressRingView

viewDidLoad:

let rings = [
    ProgressRing(color: UIColor(.RGB(232, 11, 45)), backgroundColor: UIColor(.RGB(34, 3, 11))),
    ProgressRing(color: UIColor(.RGB(137, 242, 0)), backgroundColor: UIColor(.RGB(22, 33, 0))),
    ProgressRing(color: UIColor(.RGB(0, 200, 222)), backgroundColor: UIColor(.RGB(0, 30, 28)))
]
let progressRingView = try! ConcentricProgressRingView(center: view.center, radius: radius, margin: margin, rings: rings, defaultColor: UIColor.clearColor(), defaultWidth: 18)
view.addSubview(progressRingView)

ConcentricProgressRingView, setProgress.

ring.arcs[1].setProgress(0.5, duration: 2)

, , , CABasicAnimation , . , . , !

-1

Source: https://habr.com/ru/post/1613531/


All Articles