Анимация сохраняет исходное изображение в конце

Я хочу создать анимацию исчезновения круга, и я сделал следующий код (на основе других кодов, которые я нашел в Интернете).

class CircleView: UIView {
    private var circleLayer: CAShapeLayer?

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.commonInit()
    }

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

    func commonInit() {
        self.tintColor = UIColor.lightGrayColor()
        self.backgroundColor = UIColor.clearColor()
    }

    override func drawRect(rect: CGRect) {
        super.drawRect(rect)
        self.drawCircle()
        self.addCircleAnimation()
     }

     func drawCircle() {
         let size:CGFloat = CGFloat(100)
         self.circleLayer?.removeFromSuperlayer()
         self.circleLayer = CAShapeLayer()
         self.circleLayer?.frame = self.bounds
         let radius = size / 2;
         let path = UIBezierPath(arcCenter: CGPointMake(size / 2, size / 2), radius: radius, startAngle: -CGFloat(M_PI) / 4, endAngle: 2 * CGFloat(M_PI) - CGFloat(M_PI) / 4, clockwise: true)
         self.circleLayer?.path = path.CGPath
         self.circleLayer?.fillColor = UIColor.clearColor().CGColor
         self.circleLayer?.strokeColor = self.tintColor.CGColor
         self.circleLayer?.lineWidth = CGFloat(2.0)
         self.circleLayer?.rasterizationScale = 2.0 * UIScreen.mainScreen().scale
         self.circleLayer?.shouldRasterize = true

         self.layer.addSublayer(self.circleLayer!)
      }



      func addCircleAnimation() {

           let animation = CABasicAnimation(keyPath: "strokeStart")
           animation.fromValue = 0.0
           animation.toValue = 1.0

           animation.duration = CFTimeInterval(floatLiteral: 1)
           animation.removedOnCompletion = false
           animation.fillMode = kCAFillModeBackwards
           animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)

           animation.beginTime = CACurrentMediaTime()
           animation.delegate = self
           self.circleLayer?.addAnimation(animation, forKey:"strokeStart")

      }
   }

Однако, когда анимация заканчивается, она покидает исходный круг, даже если я обнаружу с помощью animationDidStop, эффект мерцания все равно будет. Что не так с этим кодом?


person Hola Soy Edu Feliz Navidad    schedule 05.09.2016    source источник
comment
Вы можете удалить круговой слой в animationDidStop, и круг исчезнет после анимации. Вы можете попробовать код в ответе ниже.   -  person firstinq    schedule 05.09.2016
comment
Я нашел проблему, вместо того, чтобы использовать kCAFillModeBackwards, мне пришлось использовать kCAFillModeForwards. Однако, поскольку я не знаю причины этого, я замаскирую правильный ответ для лучшего объяснения.   -  person Hola Soy Edu Feliz Navidad    schedule 05.09.2016


Ответы (1)


Код для удаления кругового слоя:

class CircleView: UIView {
    private var circleLayer: CAShapeLayer?

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.commonInit()
    }

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

    func commonInit() {
        self.tintColor = UIColor.lightGrayColor()
        self.backgroundColor = UIColor.clearColor()
    }

    override func drawRect(rect: CGRect) {
        super.drawRect(rect)
        self.drawCircle()
        self.addCircleAnimation()
    }
    override func animationDidStop(anim: CAAnimation, finished flag: Bool)
    {
        self.circleLayer?.removeFromSuperlayer()
    }

    func drawCircle() {
        let size:CGFloat = CGFloat(100)
        self.circleLayer?.removeFromSuperlayer()
        self.circleLayer = CAShapeLayer()
        self.circleLayer?.frame = self.bounds
        let radius = size / 2;
        let path = UIBezierPath(arcCenter: CGPointMake(size / 2, size / 2), radius: radius, startAngle: -CGFloat(M_PI) / 4, endAngle: 2 * CGFloat(M_PI) - CGFloat(M_PI) / 4, clockwise: true)
        self.circleLayer?.path = path.CGPath
        self.circleLayer?.fillColor = UIColor.clearColor().CGColor
        self.circleLayer?.strokeColor = self.tintColor.CGColor
        self.circleLayer?.lineWidth = CGFloat(2.0)
        self.circleLayer?.rasterizationScale = 2.0 * UIScreen.mainScreen().scale
        self.circleLayer?.shouldRasterize = true

        self.layer.addSublayer(self.circleLayer!)
    }


    /** UPDATED. Add animation for strokEnd instead of strokeStart **/
    func addCircleAnimation() {

        let animation = CABasicAnimation(keyPath: "strokeEnd")
        animation.delegate = self
        animation.fromValue = 0.0
        animation.toValue = 1.0

        animation.duration = CFTimeInterval(floatLiteral: 1)
        animation.removedOnCompletion = false
        animation.fillMode = kCAFillModeBackwards
        animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)

        animation.beginTime = CACurrentMediaTime()
        animation.delegate = self
        self.circleLayer?.addAnimation(animation, forKey:"strokeEnd")


    }
}
person firstinq    schedule 05.09.2016
comment
Я знаю, как сказал, это все еще дает мне эффект мерцания, что означает, что он полностью рисуется, а затем удаляется. - person Hola Soy Edu Feliz Navidad; 05.09.2016
comment
Вы пробуете анимацию в strokeEnd и проверяете, помогает ли она. Ответ обновлен. - person firstinq; 05.09.2016
comment
Если я использую Start -> End, эффект мерцания сохраняется. Если я использую Конец -> Начало или Конец -> Конец, круг появляется, а не исчезает. - person Hola Soy Edu Feliz Navidad; 05.09.2016