受this example的啓發,我爲楔子和弧創建了自定義的CALayer
子類。允許我繪製弧形和楔形,並在其中生成動畫變化,以便它們沿徑向掃動。正確的方法來劃分CAShapeLayer
與他們的挫折之一是,顯然當你走這個路線有一個子類drawInContext()
你受限於層的框架的剪輯。使用庫存圖層,您有默認false
的masksToBounds
!但它似乎一旦你的子類路由與繪圖,那是因爲隱含和不可改變的true
。
所以我想我會嘗試一種不同的方法,而不是繼承CAShapeLayer
。而不是增加一個自定義drawInContext()
,我只需要我的變量start
和sweep
更新接收器的path
。這很好地工作,但將不再動畫,因爲它用於:
import UIKit
class WedgeLayer:CAShapeLayer {
var start:Angle = 0.0.rotations { didSet { self.updatePath() }}
var sweep:Angle = 1.0.rotations { didSet { self.updatePath() }}
dynamic var startRadians:CGFloat { get {return self.start.radians.raw } set {self.start = newValue.radians}}
dynamic var sweepRadians:CGFloat { get {return self.sweep.radians.raw } set {self.sweep = newValue.radians}}
// more dynamic unit variants omitted
// we have these alternate interfaces because you must use a type
// which the animation framework can understand for interpolation purposes
override init(layer: AnyObject) {
super.init(layer: layer)
if let layer = layer as? WedgeLayer {
self.color = layer.color
self.start = layer.start
self.sweep = layer.sweep
}
}
override init() {
super.init()
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func updatePath() {
let center = self.bounds.midMid
let radius = center.x.min(center.y)
print("updating path \(self.start) radius \(radius)")
if self.sweep.abs < 1.rotations {
let _path = UIBezierPath()
_path.moveToPoint(center)
_path.addArcWithCenter(center, radius: radius, startAngle: self.start.radians.raw, endAngle: (self.start + self.sweep).radians.raw, clockwise: self.sweep >= 0.radians ? true : false)
_path.closePath()
self.path = _path.CGPath
}
else {
self.path = UIBezierPath(ovalInRect: CGRect(around: center, width: radius * 2, height: radius * 2)).CGPath
}
}
override class func needsDisplayForKey(key: String) -> Bool {
return key == "startRadians" || key == "sweepRadians" || key == "startDegrees" || key == "sweepDegrees" || key == "startRotations" || key == "sweepRotations" || super.needsDisplayForKey(key)
}
}
是沒可能作出其動畫的價值它再生的路徑和更新?在print()
聲明中,我可以看到它在動畫期間按預期插值。我曾嘗試在各個位置添加setNeedsDisplay()
,但無濟於事。
真棒和succint的答案!前兩發子彈是否有效?我可以請求你補充說明爲什麼這種方法有效,而我的沒有?特別是第二點要做的是什麼。它顯然是克服了第一個原因。當我第一次做*時,我通過我的print()聲明注意到,當它通過動畫時(這是我用原始方法看到的迴歸),值沒有改變。 –