【问题标题】:Show file uploading progress on tableview cell Swift 4在表格视图单元格 Swift 4 上显示文件上传进度
【发布时间】:2018-09-25 17:25:26
【问题描述】:

我正在从 iCloud 中挑选文件并上传到 AWS S3。我在表格视图单元格中列出了带有进度条上传状态的选定文件。我正在维护的每个单元格都单独的文件标题和加载进度。到这里,一切都差不多完成了,但是如果我上传两个文件,tableview 第一个单元格被冻结,第二个单元格正在上传进度。

我的上传功能

private func upload(file url: URL, keyname : String, exten: String) {
    let bucket = S3BucketName
    let key = keyname
    let contentType = "text/\(exten)"
    let expression = AWSS3TransferUtilityUploadExpression()
    expression.progressBlock = progressBlock

    let task = transferUtility.uploadFile(url,
                                          bucket: bucket,
                                          key: key,
                                          contentType: contentType,
                                          expression: expression,
                                          completionHandler: completionHandler)
    task.continueWith { (task) -> Any? in
        if let error = task.error {
            DispatchQueue.main.async {
                //self.infoLabel.text = "Error: \(error.localizedDescription)"
            }
            return nil
        }
        if let uploadTask = task.result {
            self.uploadTask = uploadTask
            DispatchQueue.main.async {

                //self.infoLabel.text = "Generating Upload File"

                //self.uploadRequests.append(self.uploadTask)
                self.tableView_util.reloadData()
            }
        }
        return nil
    }
}

表格视图单元格

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "cellutil", for: indexPath) as! UtilityTableViewCell
        let item = tableArray[indexPath.row]
        cell.name_label_util.text = item.title
        cell.control_button_util.tag  = indexPath.row
        cell.control_button_util.addTarget(self, action: #selector(playpause), for: .touchUpInside)

        // MARK - Upload process
        progressBlock = { [weak self] task, progress in
            guard let strongSelf = self else { return }
            DispatchQueue.main.async {

                cell.loader_Line_util.progress = Float(progress.fractionCompleted)

                //NSLog(@"fraction completed: %f", progress.fractionCompleted);
                let percentageUploaded:Float = Float(progress.fractionCompleted) * 100
                cell.statusLabel_util.text! = NSString(format:"Uploading: %.0f%%",percentageUploaded) as String

                // Need to change
                if cell.statusLabel_util.text == "Uploading: 100%" {
                   cell.statusLabel_util.text = "File Successfully Uploaded!"
                    cell.loader_Line_util.progress = 1;
                    self?.tableView_util.reloadData()

                }
            }
        }

        completionHandler = { [weak self] task, error in
            guard let strongSelf = self else { return }
            if let error = error {
                DispatchQueue.main.async {
                }
                return
            }

【问题讨论】:

  • 您已确认并发上传实际上是同时运行的?此外,从块内部引用单元格将是一个问题,因为单元格会出列并重用。
  • 是的,它是异步过程。它正在将这两个文件上传到最新的单元格中。但第一个细胞被冻结了。我需要跟踪每个进度条需要加载的每个单元格。 @Augie ...请帮我解决这个问题
  • 我无法从您提供的代码中判断模型中发生的一切。上传任务如何与单元关联?您是否有一系列上传任务并且每个单元格都相当于一个任务?这里似乎有一些事情。每次在任何任务上发生进度事件时都会重新加载表格视图,我认为?单元格不应该只更新它的进度更改文本,而不是整个表格
  • 请检查上面我更新了我的问题。选择一个文件并上传工作正常。但是没有第一个文件上传完成如果我上传第二个文件,那么第一个单元格在第一个单元格进度条中冻结,但文件已上传。我认为需要分别跟踪每个单元格。怎么做? @奥吉
  • 请阅读Under what circumstances may I add “urgent” or other similar phrases to my question, in order to obtain faster answers? - 总结是这不是解决志愿者的理想方式,并且可能会适得其反。请不要将此添加到您的问题中。

标签: ios swift uitableview


【解决方案1】:

好的,我必须查看 AWS TransferUtility,以前从未使用过它。我认为你需要重构一些东西。我在记事本中写了这个,所以语法错误,我把一些函数留空,因为你可以添加那里的内容。

//create a class to track all your uploads in progress
Class UploadTaskTracker {

    let shared = uploadTaskTracker()

    private var tasks = [UploadTask]()

    func addTask( _ task: UploadTask){
        tasks.append(task)
    }

    fund updateTask( id: String, progress: Double){
        // get task from array and update progress value
    }

    func completeTask(id: String) {
        // remove task from tasks array
        // send out a notification to trigger tableview to reload data
    }

    func activeTasks() -> Int {
        return tasks.count
    }

    func taskAt(_ indexPath: IndexPath) -> UploadTask{
        // check for out of bounds 
        // return task
    }
    }

Class UploadTask {

    var id : String
    var progress : Double

}



// and when you start an upload task, change your expression progress block
// (and remove it from the cell.  This should all be happening in another 
// class and not be associated with your tableview 

let guid = UUID()
let uploadTask = UploadTask.init(id: guid, progress: 0.0)
UploadTaskTracker.shared.addTask(uploadTask_

expression.progressBlock = {(task, progress) in

    UploadTaskTracker.shared.updateTask(id: guid, progress: progress)
 }



// then in table view controller
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return UploadTaskTracker.shared.activeTasks()
    }

//And then in 
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    // dequeue custom uitableviewcel
    let uploadTask = UploadTaskTracker.shared. taskAt( indexPath)
    cell.load(uploadTask)

}

// create a custom uitableviewcell class
class customCell: UITableViewCell {

    @IBOutlet weak var someLabel: UILabel!
    var observers = [NSKeyValueObservation]()

    override func prepareForReuse() {
        // clear previous UI to reduce chance of user seeing obsolete text or image
        super.prepareForReuse()
        stopObservers()
    }

    func stopObservers(){
        for observer in observers{
            observer.invalidate()
        }
        observers.removeAll()
    }

    func load(_ uploadTask: UploadTask ) {

        let observer = uploadTask.observe(\.progress, options: [.initial, .new]) { [weak self] (uploadTask, change) in

            DispatchQueue.main.async {          
                someLabel.text = “\(uploadTask.progress)”
            }
        }
        observers.append(observer)
}

【讨论】:

  • 哇。好人。我会尝试在这里更新我的结果。说真的,你的及时帮助了我。 @Augie
猜你喜欢
  • 2016-04-24
  • 2019-01-21
  • 2018-07-08
  • 2014-10-22
  • 1970-01-01
  • 2015-10-12
  • 1970-01-01
  • 2021-07-04
  • 2012-01-09
相关资源
最近更新 更多