Дубликаты CAShapelayer

Я пытаюсь добавить CAShapelayer каждые 20 мс с заданными координатами x и y. Я хотел бы, чтобы форма исчезла в течение секунды (например, трассировщик). Функция, которую я создал, работает, форма создается в правильном месте и исчезает. Но я получаю лишние фигуры, которые загромождают экран.

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")

}

person duck1970    schedule 22.06.2016    source источник
comment
Не имеет отношения, но я считаю, что каждые 20 мс на удивление близки (но не равны) максимальной частоте кадров в 60 кадров в секунду. Вы используете NSTimer для этого? Почему бы не использовать CADisplayLink, который по сути является таймером, оптимизированным для обновления кадров?   -  person Rob    schedule 22.06.2016
comment
У меня есть устройство BLE с максимальной частотой обновления 50 Гц ... следовательно, 20 мс.   -  person duck1970    schedule 22.06.2016


Ответы (1)


arrow_upward
0
arrow_downward

Проблема в том, что когда анимация заканчивается, она восстанавливает strokeColor исходный цвет. Вы действительно должны установить strokeColor исходного слоя формы на clearColor(), таким образом, когда вы закончите анимацию с whiteColor() на clearColor(), он останется на уровне clearColor().

Вы также можете установить слой fillMode на kCAFillModeForwards и установить removedOnCompletion на false, и тогда слой сохранит свое состояние «конец анимации». Но лично я бы просто установил strokeColor, как указано выше, так как использование removedOnCompletion из true мешает 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()
    }
}

См. Как удалить объект CALayer из animationDidStop?

person Rob    schedule 22.06.2016
comment
Гениально и просто, спасибо за быстрый ответ. Давно мучил меня этот вопрос... - person duck1970; 22.06.2016