使用FFCircularProgressView在队列中显示动画

时间:2017-09-02 14:22:47

标签: ios swift animation

我有第一个tableViewController和第二个tableViewController。在第二个tableViewController我下载这样的文件:

enum DownloadStatus {
    case none
    case inProgress
    case completed
    case failed
}
struct item {
    var title : String!
    let link = ""
    var downloadStatus : DownloadStatus = .none

    init(title: String) {
        self.title = title
    }
 }

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    var item = self.items[indexPath.row]
    if item.downloadStatus == .inProgress || item.downloadStatus == .completed {
        print("video already downloaded")
    }
    else {
        let url = URL(string: "link\(indexPath.row + 1)")!
        let downloadManager = DownloadManager()
        downloadManager.identifier = indexPath.row
        downloadManager.tableId = self.tableId
        downloadManager.folderPath = id
        let downloadTaskLocal = downloadManager.activate().downloadTask(with: url)
        downloadTaskLocal.resume()

        downloadManager.onProgress = { (row, tableId, progress) in

            DispatchQueue.main.async {
                let appDelegate = UIApplication.shared.delegate as! AppDelegate
                if appDelegate.masterVC == nil {
                    print("master vc is nil")
                    return
                }

                if appDelegate.masterVC.tableId != tableId {
                       // different table
                       return
                }


                let indexpath = IndexPath.init(row: row, section: 0)
                let cell = appDelegate.masterVC.tableView.cellForRow(at: indexpath)
                if progress <= 1.0 {

                let progressRing = FFCircularProgressView(frame: CGRect(x: CGFloat(0), y: CGFloat(0), width: CGFloat(24), height: CGFloat(24)))
                cell?.accessoryView = progressRing
                progressRing.progress = CGFloat(progress)

                if progress == 1.0 {
                    item.downloadStatus = .completed
                    progressRing.circularState = .completed
                }

            }
       }

}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
   let item = items[indexPath.row]

    if item.downloadStatus == .inProgress {
        let progressRing = FFCircularProgressView(frame: CGRect(x: 0, y: 0, width: 80, height: 80))
        cell.tag = indexPath.row
        cell.accessoryType = UITableViewCellAccessoryType.none
        cell.accessoryView = progressRing
    }
    else {
        cell.accessoryView = nil
    }
}

这是我的DownloadManager

import Foundation
import UIKit

extension URLSession {
    func getSessionDescription () -> Int {
        // row id
        return Int(self.sessionDescription!)!
    }

    func getDebugDescription () -> Int {
        // table id
        return Int(self.debugDescription)!
    }
}

class DownloadManager : NSObject, URLSessionDelegate, URLSessionDownloadDelegate {



    static var shared = DownloadManager()
    var identifier : Int = -1
    var tableId : Int = -1
    var folderPath : String = ""
    typealias ProgressHandler = (Int, Int, Float) -> ()


    var onProgress : ProgressHandler? {
        didSet {
            if onProgress != nil {
                let _ = activate()
            }
        }
    }

    override init() {
        super.init()
    }

    func activate() -> URLSession {
        let config = URLSessionConfiguration.background(withIdentifier: "\(Bundle.main.bundleIdentifier!).background.\(NSUUID.init())")

        let urlSession = URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue())
        urlSession.sessionDescription = String(identifier)
        urlSession.accessibilityHint = String(tableId)
        return urlSession
    }

    private func calculateProgress(session : URLSession, completionHandler : @escaping (Int, Int, Float) -> ()) {
        session.getTasksWithCompletionHandler { (tasks, uploads, downloads) in
            let progress = downloads.map({ (task) -> Float in
                if task.countOfBytesExpectedToReceive > 0 {
                    return Float(task.countOfBytesReceived) / Float(task.countOfBytesExpectedToReceive)
                } else {
                    return 0.0
                }
            })

            print("tbale id \(session.accessibilityHint ?? "hit")")
            completionHandler(session.getSessionDescription(), Int(session.accessibilityHint!)!, progress.reduce(0.0, +))
        }
    }

    func urlSession(_ session: URLSession,
                    downloadTask: URLSessionDownloadTask,
                    didFinishDownloadingTo location: URL){

        let fileName = downloadTask.originalRequest?.url?.lastPathComponent
        let path = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
        let documentDirectoryPath:String = path[0]
        let fileManager = FileManager()
        var destinationURLForFile = URL(fileURLWithPath: documentDirectoryPath.appending("/\(folderPath)"))


        do {
            try fileManager.createDirectory(at: destinationURLForFile, withIntermediateDirectories: true, attributes: nil)
            destinationURLForFile.appendPathComponent(String(describing: fileName!))
            try fileManager.moveItem(at: location, to: destinationURLForFile)
        }catch(let error){
            print(error)
        }



    }

    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {

        if totalBytesExpectedToWrite > 0 {
            if let onProgress = onProgress {
                calculateProgress(session: session, completionHandler: onProgress)
            }
            let progress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
            debugPrint("Progress \(downloadTask) \(progress)")

        }
    }

    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        debugPrint("Task completed: \(task), error: \(String(describing: error))")
    }

}

我的文件下载正常。但是当我下载几个文件时,它们中的一部分现在下载,另一部分状态在队列中。对于队列中的文件,我想显示动画progressRing.startSpinProgressBackgroundLayer()。我可以在didSelectRowAt中显示这个动画,但如果我回到之前的控制器并在此控制器中再次返回我的动画未显示(因为我使用导航栏和第二个tableViewController从内存中删除)。如何在第二个tableViewController返回后显示动画?

1 个答案:

答案 0 :(得分:-1)

你可以在第一个VC的prepareFoSegue中引用第二个VC,这样如果你从第二个VC弹出第二个VC就不会被释放