2016-10-28 4 views
1

나는 단순하게 애니메이션을 적용하는 진행보기를 구현 중입니다.Swift 3 애니메이션 문제

모든 것이 잘 작동합니다. 모양으로 채우고 깜박 거리는 "strokeEnd"애니메이션입니다.

비디오 resource

코드 예제 :

circularLayer.strokeStart = 1.0 

이유가 있다는 것입니다 : 당신은 초기화에서 outAnimation의 최종 값에 strokeStart을 설정하여 그 깜박임을 해결할 수

class MaterialCircularProgressView: UIView { 

    let circularLayer = CAShapeLayer() 
    let googleColors = [ 
     UIColor(red:0.282, green:0.522, blue:0.929, alpha:1), 
     UIColor(red:0.859, green:0.196, blue:0.212, alpha:1), 
     UIColor(red:0.957, green:0.761, blue:0.051, alpha:1), 
     UIColor(red:0.235, green:0.729, blue:0.329, alpha:1) 
    ] 

    let inAnimation: CAAnimation = { 
     let animation = CABasicAnimation(keyPath: "strokeEnd") 
     animation.fromValue = 0.0 
     animation.toValue = 1.0 
     animation.duration = 1.0 
     animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn) 

     return animation 
    }() 

    let outAnimation: CAAnimation = { 
     let animation = CABasicAnimation(keyPath: "strokeStart") 
     animation.beginTime = 0.5 
     animation.fromValue = 0.0 
     animation.toValue = 1.0 
     animation.duration = 1.0 
     animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut) 

     return animation 
    }() 

    let rotationAnimation: CAAnimation = { 
     let animation = CABasicAnimation(keyPath: "transform.rotation.z") 
     animation.fromValue = 0.0 
     animation.toValue = 2 * M_PI 
     animation.duration = 2.0 
     animation.repeatCount = MAXFLOAT 

     return animation 
    }() 

    var colorIndex : Int = 0 

    override init(frame: CGRect) { 
     super.init(frame: frame) 

     circularLayer.lineWidth = 4.0 
     circularLayer.fillColor = nil 
     layer.addSublayer(circularLayer) 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 

    override func layoutSubviews() { 
     super.layoutSubviews() 

     let center = CGPoint(x: bounds.midX, y: bounds.midY) 
     let radius = min(bounds.width, bounds.height)/2 - circularLayer.lineWidth/2 

     let arcPath = UIBezierPath(arcCenter: CGPoint.zero, radius: radius, startAngle: CGFloat(M_PI_2), endAngle: CGFloat(M_PI_2 + (2 * M_PI)), clockwise: true) 

     circularLayer.position = center 
     circularLayer.path = arcPath.cgPath 

     animateProgressView() 
     circularLayer.add(rotationAnimation, forKey: "rotateAnimation") 
    } 


    func animateProgressView() { 

     circularLayer.removeAnimation(forKey: "strokeAnimation") 

     circularLayer.strokeColor = googleColors[colorIndex].cgColor 

     let strokeAnimationGroup = CAAnimationGroup() 
     strokeAnimationGroup.duration = 1.0 + outAnimation.beginTime 
     strokeAnimationGroup.repeatCount = 1 
     strokeAnimationGroup.animations = [inAnimation, outAnimation] 
     strokeAnimationGroup.delegate = self 

     circularLayer.add(strokeAnimationGroup, forKey: "strokeAnimation") 

     colorIndex += 1; 
     colorIndex = colorIndex % googleColors.count; 
    } 
} 


extension MaterialCircularProgressView: CAAnimationDelegate{ 

    override func animationDidStop(_ anim: CAAnimation, finished flag: Bool) { 
     if(flag) { 
      animateProgressView() 
     } 
    } 

} 

답변

1

CAPropertyAnimation에 의해 움직이는 속성의 실제 값은 자동으로 toValue으로 설정되지 않습니다. 이메이션은 원래 값인 0.0으로 되돌아갑니다. 그래서 한동안 완전한 원이 나타나는 이유입니다.

그러나 다음 원이 나타나기까지 지연이 있습니다. 의도 또는 다른 버그가 수정되었는지 확실하지 않습니다.

+0

이 문제가 적절합니다. –