Swift动画 —— 进度条

Swift实现动态进度条动画
本文介绍了如何使用Swift创建一个带有动画效果的进度条。首先通过CAShapeLayer绘制圆圈,然后添加点击手势以实现进度动画。在下载文件过程中,根据URLSession的代理方法更新进度。同时,为进度条添加了扩散特效,并处理了应用切回前台时动画失效的问题。最后进行了代码重构以提高可读性。

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

 let shapeLayer = CAShapeLayer()
        
    let circularPath = UIBezierPath(arcCenter: .zero, radius: 100, startAngle: 0, endAngle: CGFloat.pi * 2, clockwise: true)
        shapeLayer.path = circularPath.cgPath
        shapeLayer.position = view.center

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

这样点击之后就会画一个圆圈了。
请添加图片描述
这里有个问题就是开始的位置应该是圆的上方而不是右边,这里就需要去修改shapeLayer的transform,这样就会从圆的上方开始动画了。

        shapeLayer.transform = CATransform3DMakeRotation(-CGFloat.pi / 2, 0, 0, 1)

这里还有个问题就是圆圈的头是直线而不是圆形的,这里只需要改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.position = view.center
        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 circularPath = UIBezierPath(arcCenter: .zero, radius: 100, startAngle: 0, endAngle: CGFloat.pi * 2, clockwise: true)
        
        let trackLayer = CAShapeLayer()
        trackLayer.path = circularPath.cgPath
        trackLayer.strokeColor = UIColor.lightGray.cgColor
        trackLayer.lineWidth = 10
        trackLayer.position = view.center
        trackLayer.fillColor = UIColor.clear.cgColor
        trackLayer.lineCap = .round
            
        view.layer.addSublayer(trackLayer)
        shapeLayer.path = circularPath.cgPath
        shapeLayer.strokeEnd = 0
        shapeLayer.position = view.center
        shapeLayer.strokeColor = UIColor.red.cgColor
        shapeLayer.lineWidth = 10
        shapeLayer.fillColor = UIColor.clear.cgColor
        shapeLayer.lineCap = .round
        shapeLayer.transform = CATran
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值