2015-06-20 64 views
1

我正在寫一個計時器,類似於水平版本的時鐘應用程序中可用的計時器,只是它開始已滿並且向下運行爲空。因爲我使用drawRect方法進行動畫製作,所以我實現了計時器,它適用於較大的時間,但它無法快速進行動畫快速動畫處理(我的動畫時間最快爲400ms)。爲了說明這一點,這是我的計時器代碼:iOS動畫:CADisplayLink vs CAShapeLayer

class SSTimerView: UIView { 
    var timer: NSTimer? 
    var startAngle: CGFloat = (CGFloat) (M_PI * 1.5) 
    var endAngle: CGFloat = (CGFloat) (M_PI * 1.5) + (CGFloat) (M_PI * 2) 
    var percent: CGFloat? = 100 

    required init(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
    } 

    override func drawRect(rect: CGRect) { 
     var bezierPath = UIBezierPath() 
     //Create our arc with the correct angles 
     bezierPath.addArcWithCenter(CGPointMake(rect.size.width/2, rect.size.height/2), 
      radius: 130, 
      startAngle: startAngle, 
      endAngle: (endAngle - startAngle) * (percent!/100.0) + startAngle, 
      clockwise: true 
     ) 
     //Set the display for the path and stroke it. 
     bezierPath.lineWidth = 20 
     Slide.sharedInstance.currentInstruction!.colorFamily.lighterColor.setStroke() 
     bezierPath.stroke() 
    } 
} 

我一直在閱讀CADisplayLink了,我認爲這可能是一個可行的選擇,但我也聽說CADisplayLink並不適用於所有情況。這是他們中的一員嗎?如果CADisplayLink在這裏不合適,我應該使用哪個CA類?

回答

1

如您所知,手動動畫CADisplayLink始終優於NSTimer。 (有關討論的原因,請參閱WWDC 2014視頻Building Interruptible and Responsive Interactions,從視頻開始約14分鐘。)因此,如果您堅持現有模式,請務必轉至CADisplayLink

但是,如果你想動畫這個路徑的繪製,CABasicAnimation要容易得多:

var shapeLayer: CAShapeLayer! 

func addShapeLayer() { 
    shapeLayer  = CAShapeLayer() 
    let startAngle = CGFloat(M_PI * 1.5) 
    let endAngle = startAngle + CGFloat(M_PI * 2) 

    let bezierPath = UIBezierPath() 

    bezierPath.addArcWithCenter(CGPointMake(view.bounds.size.width/2, view.bounds.size.height/2), 
     radius: 130.0, 
     startAngle: startAngle, 
     endAngle: endAngle, 
     clockwise: true 
    ) 

    shapeLayer.path  = bezierPath.CGPath 
    shapeLayer.strokeColor = UIColor.blueColor().CGColor 
    shapeLayer.fillColor = UIColor.clearColor().CGColor 
    shapeLayer.lineWidth = 20.0 

    view.layer.addSublayer(shapeLayer) 
} 

func animateShapeLayer() { 
    let animation  = CABasicAnimation(keyPath: "strokeEnd") 
    animation.duration = 0.4 
    animation.fromValue = 0.0 
    animation.toValue = 1.0 
    shapeLayer.addAnimation(animation, forKey: "strokeEndAnimation") 
} 

CADisplayLink的做法是巨大的,如果你需要更多的個性化的行爲,但如果你只是想動畫的繪製一段時間內的路徑,CABasicAnimation是最簡單的(並且可能提供最佳性能)。

+0

我很喜歡你的建議。我最初使用它,但我對隱式動畫非常不滿。所以,我修改了你的解決方案,包括CADisplayLink,其中我正在計算和動畫計算每個幀的計時器應該具有的填充百分比。這對我來說工作得非常好,因爲我可以將控制邏輯添加到定時器(「如果定時器用完並滿足這些條件,則......」),暫停並重新啓動定時器,並且它更有效地運行CONSIDERABLY(< NSTimer的1/3 CPU使用率)。 –