Oranutachi
Oranutachi

Reputation: 1279

How can I update the progress bar in the UITableView cells when they are not visible yet

I ran into a problem: I have a Table View in which I display a list of user's files in the cloud storage. I have successfully implemented downloading these files to the device by clicking on the button located on the cell. After clicking on it, a progress bar appears on the cell, which displays the progress of the file download. Now I need to implement the ability to download all files by clicking on the Download All button. But I ran into a problem: I can download all the files together, but I can't display the download progress in those cells that are outside of Table View. I want the progress bar to display the current progress even when the cells are not visible. And when I scrolled down the Table View so that when a new cell appears, I see the current loading progress. How can i do this? I have tried many options, but none of them work correctly. Below you can see my code at the moment:

class SourceFileListViewController: UIViewController {
    private var isDownloadAllButtonPressed: Bool = false
    private var cellsWithFilesIndexPathes: [IndexPath] = []
    private var currentProgress: [IndexPath : Double] = [:]
    ...
    @objc private func barButtonAction() {
    isDownloadAllButtonPressed = true
    for indexPath in cellsWithFilesIndexPathes {
        fileListSource?.downloadFile(path: fileListSource?.files[indexPath.row].path,
                                     pathComponent: fileListSource?.files[indexPath.row].name,
                                     completion: { progress in
                                        self.currentProgress[indexPath] = progress
                              
        }, callback: {
            self.getTrackNames {
                self.tableView.reloadRows(at: [indexPath], with: .automatic)
            }
        })
    }
}

extension SourceFileListViewController: UITableViewDelegate, UITableViewDataSource {
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: SourceFileListCell.reuseId,
                                                 for: indexPath) as! SourceFileListCell
        cell.progressBar.isHidden = true
        cell.delegate = self
        cell.progressBar.setProgress(to: 0)
        ....
        //Here I check the file this or folder
        let entry = fileListSource?.unreformedFileList[indexPath.row]
        switch entry {
        case _ as Files.FileMetadata:
            cell.downloadButton.isHidden = false
            cell.artworkImageView.image = UIImage(systemName: "music.note")

            //If this is a file, I put its indexPath in an array so that it can be downloaded by the Download All button
            cellsWithFilesIndexPathes.append(indexPath)
            if isDownloadAllButtonPressed {
            cell.progressBar.isHidden = false
            guard let progress = currentProgress[indexPath] else { return cell }
            cell.progressBar.setProgress(to: progress)
        }
        case _ as Files.FolderMetadata:
            cell.downloadButton.isHidden = true
            cell.artworkImageView.image = UIImage(systemName: "folder.fill")
        default:
            break
        }
        
        //Here I check if there is such a file in the user library
        guard let fileName = fileListSource?.files[indexPath.row].name else { return cell }
        if trackNames.contains(fileName) {
            cell.downloadButton.setImage(UIImage(systemName: "checkmark.circle.fill"), for: .normal)
        } else {
            cell.downloadButton.setImage(UIImage(systemName: "icloud.and.arrow.down"), for: .normal)
        }
        
        return cell
        
    }
}

Upvotes: 0

Views: 1002

Answers (1)

Lalo
Lalo

Reputation: 438

Your data source needs to store the current progress so that you can call cell.progressBar.setProgress in cellForRowAt:IndexPath:

You could initialize an array with the number of items you are showing all with an initial value of 0 and in your downloadFile completion block update the array at indexPath.row with the new progress.

Upvotes: 1

Related Questions