Reputation: 1279
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
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