Swift动画 —— 进度条(二)

最后需要完成的效果:

在这里插入图片描述

一般来说,进度条是用来监听下载进度的,接下来需要模拟下载文件的过程,并且让进度条根据下载进度发生相应的改变。 创建一个方法来下载文件,这里使用URLSession以方便观察下载的情况。这里需要遵守URLSessionDownloadDelegate,并实现代理方法,否则会报错。

func beginDownloadingFile() {
        let configuration = URLSessionConfiguration.default
        let operationQueue = OperationQueue()
        let urlSession = URLSession(configuration: configuration, delegate: self, delegateQueue: operationQueue)
        
        guard let url = URL(string: urlString) else { return }
        let downloadTask = urlSession.downloadTask(with: url)
        downloadTask.resume()
    }
复制代码

接下来在URLSession的代理方法中,根据已经写的data和总共需要写的data计算出百分比,然后根据得出的百分比改变shapeLayer的strokeEnd。这里改变strokeEnd的时候需要放在主线程,否则视图不会发生改变。

 func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
        let percentage = CGFloat(totalBytesWritten) / CGFloat(totalBytesExpectedToWrite)
        
        DispatchQueue.main.async {
            self.shapeLayer.strokeEnd = percentage
        }
        
        print(percentage)
    }
复制代码

接下来需要创建一个label放在shapelayer的中间进行显示。 创建一个UILabel让VC持有,文字为Start,文字居中对齐,字体大小为加粗32号,字体颜色为黑色。

   let percentageLabel: UILabel = {
        let label = UILabel()
        label.text = "Start"
        label.textAlignment = .center
        label.font = UIFont.boldSystemFont(ofSize: 32)
        label.textColor = .black
        return label
    }()
    
复制代码

在视图中添加percentageLabel为视图的子view,设置好label的frame,并将其放在视图中心。

 view.addSubview(percentageLabel)
 percentageLabel.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
 percentageLabel.center = view.center
复制代码

接下来需要在下载任务开始时,将percentageLabel的文字改为对应的百分比。 这个就在刚才URLSession的代理方法里面设置strokeEnd的地方设置percentageLabel的text就好了。这里注意设置text也需要在主线程里面。

        DispatchQueue.main.async {
            self.percentageLabel.text = "\(Int(percentage * 100))%"
            self.shapeLayer.strokeEnd = percentage
        }
复制代码

到这里进度条就会跟着下载的进度前进,并且在中间显示白分比了。

在这里插入图片描述

完整代码:

import UIKit

class ViewController: UIViewController,URLSessionDownloadDelegate {

    
    
    let shapeLayer = CAShapeLayer()
    let percentageLabel: UILabel = {
        let label = UILabel()
        label.text = "Start"
        label.textAlignment = .center
        label.font = UIFont.boldSystemFont(ofSize: 32)
        label.textColor = .black
        return label
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        view.addSubview(percentageLabel)
        percentageLabel.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
        percentageLabel.center = view.center
        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 = CATransform3DMakeRotation(-CGFloat.pi / 2, 0, 0, 1)

            
        view.layer.addSublayer(shapeLayer)
        view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap)))
    }
    
    let urlString = "https://firebasestorage.googleapis.com/v0/b/firestorechat-e64ac.appspot.com/o/intermediate_training_rec.mp4?alt=media&token=e20261d0-7219-49d2-b32d-367e1606500c"
    
    func beginDownloadingFile() {
        shapeLayer.strokeEnd = 0
        let configuration = URLSessionConfiguration.default
        let operationQueue = OperationQueue()
        let urlSession = URLSession(configuration: configuration, delegate: self, delegateQueue: operationQueue)
        
        guard let url = URL(string: urlString) else { return }
        let downloadTask = urlSession.downloadTask(with: url)
        downloadTask.resume()
    }
    
    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
        
    }
    
    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
        let percentage = CGFloat(totalBytesWritten) / CGFloat(totalBytesExpectedToWrite)
        
        DispatchQueue.main.async {
            self.percentageLabel.text = "\(Int(percentage * 100))%"
            self.shapeLayer.strokeEnd = percentage
        }
        
        print(percentage)
    }
    
    @objc func handleTap() {
        
        beginDownloadingFile()
//        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/7016633402661011492
今日推荐