Swift动画 —— 进度条(一)

最后需要完成的效果:

在这里插入图片描述

首先要做的就是用CAShapeLayer画一个圆。这里先创建一个路径,把圆的中心放在视图的中心,半径设为100,然后设置起始角度和结束角度,并将clockwise设为true。然后将shapeLayer的路径设为刚才创建的路径,最后将shapeLayer添加到view的layer的sublayer中。

 let shapeLayer = CAShapeLayer()
        
        let center = view.center
        let circularPath = UIBezierPath(arcCenter: center, radius: 100, startAngle: 0, endAngle: CGFloat.pi * 2, clockwise: true)
        shapeLayer.path = circularPath.cgPath
            
        view.layer.addSublayer(shapeLayer)
复制代码

接下来在shapeLayer外面添加一圈红色的圆圈。

 shapeLayer.strokeColor = UIColor.red.cgColor
 shapeLayer.lineWidth = 10
复制代码

效果如下:

在这里插入图片描述

接下来为view添加一个点击手势,以便后面来进行外面圆圈的动画。

view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap)))
复制代码

添加响应方法

@objc func handleTap() {
}
复制代码

在添加外面圆圈的动画时候需要用到shapeLayer,所以把shapeLayer放到外面声明让VC持有。 在viewDidLoad中将shapeLayer的.strokeEnd 设为0

 shapeLayer.strokeEnd = 0
复制代码

之后在handleTap中为shapeLayer添加动画。

let basicAnimation = CABasicAnimation(keyPath: "strokeEnd")
        basicAnimation.toValue = 1
        basicAnimation.duration = 2
        shapeLayer.add(basicAnimation, forKey: "stokeAnimation")
复制代码

这样点击之后就会画一个圆圈了。

请添加图片描述

这里有个问题就是开始的位置应该是圆的上方而不是右边,这里就需要去修改circularPath的startAngle,这样就会从圆的上方开始动画了。

  let circularPath = UIBezierPath(arcCenter: center, radius: 100, startAngle: -CGFloat.pi / 2, endAngle: CGFloat.pi * 2, clockwise: true)
复制代码

这里还有个问题就是圆圈的头是直线而不是圆形的,这里只需要改shapeLayer的lineCap就可以了。

 shapeLayer.lineCap = .round
复制代码

接下来移除掉圆圈中间的黑色部分,这里修改shapeLayer的填充色为无色。

 shapeLayer.fillColor = UIColor.clear.cgColor
复制代码

接下来为进度条添加一个底部轨道(track layer)。

    let trackLayer = CAShapeLayer()
        trackLayer.path = circularPath.cgPath
        trackLayer.strokeColor = UIColor.lightGray.cgColor
        trackLayer.lineWidth = 10
        trackLayer.fillColor = UIColor.clear.cgColor
        trackLayer.lineCap = .round
复制代码

现在的效果:

请添加图片描述

完整代码:

import UIKit

class ViewController: UIViewController {
    
    let shapeLayer = CAShapeLayer()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        
        let center = view.center
        let circularPath = UIBezierPath(arcCenter: center, radius: 100, startAngle: -CGFloat.pi / 2, endAngle: CGFloat.pi * 2, clockwise: true)
        
        let trackLayer = CAShapeLayer()
        trackLayer.path = circularPath.cgPath
        trackLayer.strokeColor = UIColor.lightGray.cgColor
        trackLayer.lineWidth = 10
        trackLayer.fillColor = UIColor.clear.cgColor
        trackLayer.lineCap = .round
            
        view.layer.addSublayer(trackLayer)
        shapeLayer.path = circularPath.cgPath
        shapeLayer.strokeEnd = 0
        shapeLayer.strokeColor = UIColor.red.cgColor
        shapeLayer.lineWidth = 10
        shapeLayer.fillColor = UIColor.clear.cgColor
        shapeLayer.lineCap = .round
            
        view.layer.addSublayer(shapeLayer)
        view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap)))
    }

    @objc func handleTap() {
        let basicAnimation = CABasicAnimation(keyPath: "strokeEnd")
        basicAnimation.toValue = 1
        basicAnimation.duration = 2
        basicAnimation.fillMode = .forwards
        basicAnimation.isRemovedOnCompletion = false
        shapeLayer.add(basicAnimation, forKey: "stokeAnimation")
        
    }

}

复制代码

猜你喜欢

转载自juejin.im/post/7016618322586238984