如何反向绘制圆圈动画?

时间:2019-02-10 16:06:53

标签: ios swift xcode animation

我创建了画圆动画。 当用户点击按钮上的触地得分时,动画将变为100%,但是当用户将手指移开时,动画将暂停。 我现在要做的是使此动画达到0%(起始值)而不是暂停。

var shapeLayer = CAShapeLayer()
var cabAnim = CABasicAnimation()
var firstAnimation = true

 override func viewDidLoad() {
    super.viewDidLoad()

    let button = UIButton(frame: CGRect(x: 100, y: 200, width: 100, height: 50))
    button.backgroundColor = .blue
    button.setTitle("123", for: .normal)
    button.addTarget(self, action: #selector(startCircleAnimation), for: .touchDown)
    button.addTarget(self, action: #selector(endCircleAnimation), for: .touchUpInside)
    self.view.addSubview(button)

    let circlePath = UIBezierPath(arcCenter: CGPoint(x: 0, y: 0), radius: CGFloat(50), startAngle: -CGFloat(Double.pi/2), endAngle: CGFloat(Double.pi * 3/2), clockwise: true)
    shapeLayer.path = circlePath.cgPath
    shapeLayer.position = CGPoint(x: self.view.frame.midX, y: self.view.frame.midY)

    shapeLayer.fillColor = UIColor.clear.cgColor
    shapeLayer.strokeColor = UIColor.red.cgColor
    shapeLayer.lineWidth = 3.0
    shapeLayer.strokeEnd = 0.0

    self.view.layer.addSublayer(shapeLayer)
}

 @objc func startCircleAnimation() {
    if (firstAnimation) {
        firstAnimation = false
        circleAnimation()
    } else {
        resumeAnimation(layer: shapeLayer)
    }
}
 @objc func endCircleAnimation() {
   pauseAnimation(layer: shapeLayer)
}

func circleAnimation() {
    cabAnim = CABasicAnimation(keyPath: "strokeEnd")
    cabAnim.duration = 1.5
    cabAnim.repeatCount = 1
    cabAnim.fromValue = 0.0
    cabAnim.toValue = 1.0
    let cam = CAMediaTimingFunctionName.linear
    cabAnim.timingFunction = CAMediaTimingFunction(name: cam)
    shapeLayer.strokeEnd = 1.0
    shapeLayer.add(cabAnim, forKey: "animateCircle")
}


func pauseAnimation(layer: CALayer) {
    let pausedTime: CFTimeInterval = layer.convertTime(CACurrentMediaTime(), from: nil)
    layer.speed = 0.0
    layer.timeOffset = pausedTime
}

func resumeAnimation(layer: CALayer) {
    let resAnimation = CABasicAnimation(keyPath: "strokeEnd")
    let pausedTime: CFTimeInterval = layer.timeOffset
    layer.speed = 1.0
    layer.timeOffset = 0.0
    layer.beginTime = 0.0
    let timeSincePause: CFTimeInterval = layer.convertTime(CACurrentMediaTime(), from: nil) - pausedTime
    layer.beginTime = timeSincePause
}

我如何使价值变为零而不是暂停?

编辑: 我希望它从currentValue移到0(例如,我按住按钮动画达到50%,然后我从按钮上移开手指,然后动画达到0%)

1 个答案:

答案 0 :(得分:2)

您可以使用此功能创建后向动画,它将动画从100绘制为0。我添加了整个项目,您可以看看。

@IBAction func backward(_ sender: Any) {

        let basicAnimation = CABasicAnimation(keyPath: "strokeEnd")
        basicAnimation.fromValue = 1
        basicAnimation.toValue = 0
        basicAnimation.duration = 2
        basicAnimation.fillMode = kCAFillModeBackwards
        basicAnimation.isRemovedOnCompletion = false

        // Callback function
        CATransaction.setCompletionBlock {
           print("end animation")
        }

        shapeLayer.add(basicAnimation, forKey: "urSoBasic")
    }

enter image description here

创建ShapeLayer

in most cases, you can call creating shape layer on `ViewDidLoad`

func createShape() {
        // let's start by drawing a circle somehow
        let center = view.center
        let trackLayer = CAShapeLayer()

        let circularPath = UIBezierPath(arcCenter: center, radius: 100, startAngle: -CGFloat.pi / 2, endAngle: 2 * CGFloat.pi, clockwise: true)
        trackLayer.path = circularPath.cgPath

        trackLayer.strokeColor = UIColor.lightGray.cgColor
        trackLayer.lineWidth = 10
        trackLayer.fillColor = UIColor.clear.cgColor
        trackLayer.lineCap = kCALineCapRound
        view.layer.addSublayer(trackLayer)

        shapeLayer.path = circularPath.cgPath
        shapeLayer.strokeColor = UIColor.red.cgColor
        shapeLayer.lineWidth = 10
        shapeLayer.fillColor = UIColor.clear.cgColor
        shapeLayer.lineCap = kCALineCapRound
        shapeLayer.strokeEnd = 0

        view.layer.addSublayer(shapeLayer)
    }

前进动作

@IBAction func forward(_ sender: Any) {

        let basicAnimation = CABasicAnimation(keyPath: "strokeEnd")        
        basicAnimation.toValue = 1
        basicAnimation.duration = 2
        basicAnimation.fillMode = kCAFillModeForwards
        basicAnimation.isRemovedOnCompletion = false
        shapeLayer.add(basicAnimation, forKey: "urSoBasic")
    }

后退操作

@IBAction func backward(_ sender: Any) {

        let basicAnimation = CABasicAnimation(keyPath: "strokeEnd")
        basicAnimation.fromValue = 1
        basicAnimation.toValue = 0
        basicAnimation.duration = 2
        basicAnimation.fillMode = kCAFillModeBackwards
        basicAnimation.isRemovedOnCompletion = false
        // Callback function
        CATransaction.setCompletionBlock {
           print("end animation")
        }
        shapeLayer.add(basicAnimation, forKey: "urSoBasic")
    }

在保持或恢复逻辑上,您可以使用这些代码。