出于自动化目的,是否将Swift结构转换/包装为NSValue?
我有一个自定义的出于自动化目的,是否将Swift结构转换/包装为NSValue?,swift,struct,swift2,caanimation,nsvalue,Swift,Struct,Swift2,Caanimation,Nsvalue,我有一个自定义的CALayer子类,它绘制一条圆弧。它看起来像: class ArcLayer: CALayer { var strokeColor:UIColor = UIColor.blackColor() { didSet { self.setNeedsDisplay() }} var strokeWidth:CGFloat = 1.0 { didSet { self.setNeedsDisplay() }} var strokeCap:CGLineCap = .B
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)
}
}
我使用的是一个自定义子类,因为虽然CAShapeLayer
的path
是可设置动画的,但它不会以您希望圆弧旋转的方式设置动画。以上工作。开始/扫掠的动画会产生所需的效果
不过我想换一下。我有一个Angle
struct(请参见),我宁愿使用它,而不是原始弧度CGFloat值。将这两个变量的类型更改为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")
我不能只是将这些值更改为角度值
值:
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相交的拐角处的情况可能会让人非常困惑。Angle
是一个结构,它不符合任何对象。为了符合任何对象
,您需要将其更改为类,或将其包装为类,如框
:
final class Box<T> {
let value: T
init(_ value: T) { self.value = value }
}
最终类框{
let值:T
init(value:T){self.value=value}
}
尽管如此,这不太可能奏效CABasicAnimation
对如何:
- 整数和双精度
- CGRect、CGPoint、CGSize和CGAffineTransform结构
- CATTransform3D数据结构
- CGColor和CGImage参考
我不相信有任何方法可以添加到这个列表中。我不相信您可以使用cabasicanitation
插入任意类型。你需要从一个数字变成一个数字,所以这基本上就是你上面的代码
当然,您可以将sweep radians
设置为一个计算属性,只向前移动到sweep
,并且可以从度(0)到度(360)设置动画。所以你可以得到你想要的大部分实际利益;只是不需要在某个时刻手动转换为数字
现在,如果这是Mac,您可以子类化NSAnimation
,并构建您自己的动画制作程序来完成这项工作。有关这方面的讨论,请参见。但是在iOS上没有NSAnimation
,我不相信您可以用同样的方式将CAAnimation
子类化。CAAnimation上没有“progress”委托方法
我认为您应该尝试使用NSValue的init(指针指针:UnsafePointer)
。您可以使用func with UnsafePointer(inout arg:T、@noescape\body:UnsafePointer throws->Result)获取指向您的角度的指针
实例(请参阅以获取参考)。
另外,将NSValue包装的东西传递给核心动画的想法通常是一种可行的技术。现在还不清楚CA是否会打开角度。祝你好运