I have a custom CALayer
subclass that draws a circular arc. It looks something like:
class ArcLayer: CALayer {
var strokeColor:UIColor = UIColor.blackColor() { didSet { self.setNeedsDisplay() }}
var strokeWidth:CGFloat = 1.0 { didSet { self.setNeedsDisplay() }}
var strokeCap:CGLineCap = .Butt { didSet { self.setNeedsDisplay() }}
var startRadians:CGFloat = 0.0 { didSet { self.setNeedsDisplay() }}
var sweepRadians:CGFloat = Tau { didSet { self.setNeedsDisplay() }}
// other init's omitted for brevity
override init(layer: AnyObject) {
super.init(layer: layer)
if let layer = layer as? ArcLayer {
self.strokeColor = layer.strokeColor
self.strokeWidth = layer.strokeWidth
self.strokeCap = layer.strokeCap
self.startRadians = layer.startRadians
self.sweepRadians = layer.sweepRadians
}
}
override func drawInContext(ctx: CGContext) {
...
}
override class func needsDisplayForKey(key: String) -> Bool {
return key == "startRadians" || key == "sweepRadians" || super.needsDisplayForKey(key)
}
}
I'm using a custom subclass, because while the path
of a CAShapeLayer
is animatable, it does not animate in the way you would expect the arc to rotate around. The above works. Animations to the start/sweep produce the desired effect.
I want to change it though. I have an Angle
struct (see this answer) which I would rather use than the raw radian CGFloat value. Changing the type of those two vars to Angle
compiles fine. And the original display works too (after making the appropriate conversions/extractions from the Angle
vars). THE PROBLEM is being able to animate those vars now. Where as before I might have written some code like:
let sweep = CABasicAnimation(keyPath: "sweepRadians")
sweep.fromValue = 0.0 // raw radians value
sweep.toValue = Tau // raw radians value for one rotation
sweep.duration = 10.seconds
sweep.repeatCount = 0
self.blueRing.addAnimation(sweep, forKey: "sweepRadians")
I can't just change those to Angle
values:
sweep.fromValue = Angle(raw: 0, unit: .Rotations)
sweep.toValue = Angle(raw: 0, unit: .Rotations)
That results in a
cannot assign value of type 'Angle' to type of 'AnyObject?'
I'm hoping that the solution is that I need to somehow convert/wrap my Angle
values as NSValue objects? Is that indeed correct? Can it be done? How so?
I really like Swift, but the corner cases where it intersects with Objc can be really confusing.