2016-06-22 3 views
1

私は与えられたx座標とy座標に20msごとにCAShapelayerを1回追加しようとしています。私は形状が1秒以上消えることを望んでいます(トレーサーのように)。私が作成した機能が動作し、正しい位置にシェイプが作成され、フェードアウトします。しかし、私は余分な図形を画面の上に乱雑に残しています。CAShapelayer Duplicates

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

無関係参照してください、私は60fpsでの最大フレームレート不思議に近い(しかし、等しくない)であることを「20msごと」を見つけます。あなたは 'NSTimer'を使っていますか?基本的にフレームの更新に最適化されたタイマである 'CADisplayLink'を使用してみませんか? – Rob

+1

私はリフレッシュ周波数が最大50HzのBLEデバイスを持っています...したがって、20ms – duck1970

答えて

0

問題は、アニメーションが終了したとき、それは元の色にstrokeColorを復元することです。 whiteColor()からclearColor()にアニメーション化すると、元の図形レイヤーのstrokeColorclearColor()に設定すると、clearColor()のままになります。

また、層のfillModekCAFillModeForwardsに設定してfalseremovedOnCompletionを設定し、その層は、その「最後のアニメーションの」状態を保持する必要がありますすることができます。しかし、removedOnCompletiontrueを使用するとanimationDidStop(下記参照)と干渉するので、私は個人的には上記のようにstrokeColorを設定するだけです。


また、私はそれはもはや見えますが、それはメモリを消費し続けないないように、それがアニメーションで行われています一度あなたも層を除去することを示唆しているかもしれません。

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