我有一个CALayer
绘制圆弧的自定义子类。它看起来像:
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)
}
}
我正在使用自定义子类,因为虽然path
aCAShapeLayer
是可动画的,但它不会以您期望圆弧旋转的方式动画。以上工作。开始/扫描的动画会产生所需的效果。
我想改变它。我有一个Angle
结构(见这个答案),我宁愿使用它而不是原始弧度 CGFloat 值。将这两个变量的类型更改为可以Angle
正常编译。Angle
并且原始显示也有效(在从变量中进行适当的转换/提取之后)。问题是现在能够为这些变量设置动画。和以前一样,我可能已经编写了一些代码,例如:
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")
我不能只是将它们更改为Angle
值:
sweep.fromValue = Angle(raw: 0, unit: .Rotations)
sweep.toValue = Angle(raw: 0, unit: .Rotations)
这导致一个
cannot assign value of type 'Angle' to type of 'AnyObject?'
我希望解决方案是我需要以某种方式将我的Angle
值转换/包装为 NSValue 对象?这真的正确吗?可以做到吗?怎么会这样?
我真的很喜欢 Swift,但是它与 Objc 相交的极端情况可能真的很令人困惑。