2016-06-22 60 views
1

我想添加一個CAShapelayer每20ms一次給定的x和y座標。我希望這個形狀能夠在一秒之內消失(就像一個示蹤劑)。我創建的函數工作,形狀創建在正確的位置並消失。但是我得到了額外的形狀留在屏幕上。CAShapelayer重複

func shadowBall (x: CGFloat, y: CGFloat){ 

    let xpos : CGFloat = ((self.frame.width/2) + x) 
    let ypos : CGFloat = ((self.frame.height/2) + y) 

    let shadowBall = CAShapeLayer() 
    let shadowBalllRadius :CGFloat = 4 
    let shadowBallPath : UIBezierPath = UIBezierPath(ovalInRect: CGRect(x: xpos, y: ypos, width: CGFloat(shadowBalllRadius*2), height: CGFloat(shadowBalllRadius*2))) 

    shadowBall.path = shadowBallPath.CGPath 
    shadowBall.fillColor = UIColor.clearColor().CGColor 
    shadowBall.strokeColor = UIColor.whiteColor().CGColor 
    shadowBall.lineWidth = 0.5 

    let animation: CABasicAnimation = CABasicAnimation(keyPath: "strokeColor") 
    animation.fromValue = UIColor.whiteColor().CGColor 
    animation.toValue = UIColor.clearColor().CGColor 
    animation.duration = 1.0; 
    animation.repeatCount = 0; 
    animation.removedOnCompletion = true 
    animation.additive = false 

    self.layer.addSublayer(shadowBall) 
    shadowBall.addAnimation(animation, forKey: "strokeColor") 

} 
+0

無關,但我覺得「每20ms」是好奇地靠近(但不等於)60個FPS的最大幀速率。你使用'NSTimer'嗎?爲什麼不使用'CADisplayLink',它本質上是一個針對幀更新而優化的定時器? – Rob

+1

我有一個刷新頻率最高爲50Hz的BLE設備...因此20ms – duck1970

回答

0

問題是,當動畫結束時,它會將strokeColor恢復爲原始顏色。您應該將原始形狀圖層的strokeColor設置爲clearColor(),這樣,當您完成從whiteColor()clearColor()的動畫時,它將保持在clearColor()

您還可以設置圖層的fillModekCAFillModeForwards並設置removedOnCompletionfalse,並且將有層保持其狀態「動畫的結束」。但我個人只會設置strokeColor如上所述,因爲使用removedOnCompletiontrue干擾animationDidStop(見下文)。


另外,我可能會建議您在動畫完成後也刪除圖層,以免它繼續佔用內存,儘管它不再可見。

func shadowBall (x: CGFloat, y: CGFloat) { 
    let xpos: CGFloat = ((self.frame.width/2) + x) 
    let ypos: CGFloat = ((self.frame.height/2) + y) 

    let shadowBall = CAShapeLayer() 
    let shadowBalllRadius: CGFloat = 4 
    let shadowBallPath = UIBezierPath(ovalInRect: CGRect(x: xpos, y: ypos, width: CGFloat(shadowBalllRadius*2), height: CGFloat(shadowBalllRadius*2))) 

    shadowBall.path = shadowBallPath.CGPath 
    shadowBall.fillColor = UIColor.clearColor().CGColor 
    shadowBall.strokeColor = UIColor.clearColor().CGColor 
    shadowBall.lineWidth = 0.1 

    let animation = CABasicAnimation(keyPath: "strokeColor") 
    animation.fromValue = UIColor.whiteColor().CGColor 
    animation.toValue = UIColor.clearColor().CGColor 
    animation.duration = 1.0 
    animation.repeatCount = 0 
    animation.removedOnCompletion = true 
    animation.additive = false 

    animation.delegate = self 
    animation.setValue(shadowBall, forKey: "animationLayer") 

    self.layer.addSublayer(shadowBall) 
    shadowBall.addAnimation(animation, forKey: "strokeColor") 
} 

override func animationDidStop(anim: CAAnimation, finished flag: Bool) { 
    if let layer = anim.valueForKey("animationLayer") as? CALayer { 
     layer.removeFromSuperlayer() 
    } 
} 

How to remove a CALayer-object from animationDidStop?

+0

輝煌而簡單,感謝您的快速回復。一直在糾纏我這個問題... – duck1970