Nate23VT
Nate23VT

Reputation: 423

Swift TableView ProgressView indicator on multiple rows on single select

I have a tableview list that has a select action tied to it. When the user selects the row, it gives them a prompt and begins to download a file and displays progress using a progressive indicator. For some reason, the indicator is being displayed every 12 records from the selection. Why is this happening... am I selecting the cell incorrectly?

Here is my code:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let cell = self.tableView.cellForRow(at: indexPath) as! downloadCell
    let cellName = CurrentFiles[indexPath.row].labelName
    let internalName = CurrentFiles[indexPath.row].internalName
    let fileLocation = CurrentFiles[indexPath.row].fileName
    let safeURL = fileLocation.addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed)
    let fileExtension = CurrentFiles[indexPath.row].fileExtension
    let fileDate = CurrentFiles[indexPath.row].lastUpdate
    if (cell.progressView.isHidden) && (cell.fileStatus == "Installed") && (cell.fileIcon.image ==  nil) {
        let fileLoc = getSharedFilePath(appGroup:applicationGroup,sharedFilename:"\(internalName).\(fileExtension)")
        let defaults = UserDefaults.standard
        defaults.set(fileLoc, forKey: "loadmap")
        defaults.set(cellName, forKey: "loadmapName")
        performSegue(withIdentifier: "gotoMap", sender: self)
    } else if (cell.progressView.isHidden) {
        alertControllerMsg(msgStyle: UIAlertControllerStyle.alert,msgTitle: "Download File", msgBody: "Are you sure you want to download \(cellName)?", cancelLbl: "Cancel", actionLbl: "Download", complete: {
            cell.fileStatus = "Installed"      //prevent double download
            //download file
            let destination: (URL, HTTPURLResponse) -> (URL, DownloadRequest.DownloadOptions) = {
                (temporaryURL, response) in
                if let directoryURL = FileManager().containerURL(forSecurityApplicationGroupIdentifier: applicationGroup), let suggestedFilename = response.suggestedFilename {
                    let filePath = directoryURL.appendingPathComponent("\(suggestedFilename)")
                    return (filePath, [.removePreviousFile, .createIntermediateDirectories])
                }
                return (temporaryURL, [.removePreviousFile, .createIntermediateDirectories])
            }
            if self.reachability.isReachableViaWiFi {
                cell.progressView.isHidden = false
                //BackendAPI is used to allow for downloads in background
                BackendAPIManager.sharedInstance.alamoFireManager.download(safeURL!, to: destination)
                    .downloadProgress { progress in
                        cell.fileIcon.image =  nil
                        cell.progressView.setProgress(Float(progress.fractionCompleted), animated: true)
                        cell.pctLabel.text = "\(String(format:"%g",round(progress.fractionCompleted*100)))%"
                    }.response { response in
                        cell.pctLabel.text = nil
                        cell.progressView.isHidden = true
                        cell.additionalLbl.text = nil
                        UserDefaults(suiteName: applicationGroup)!.set(fileDate, forKey: internalName)
                        cell.fileStatus = "Installed"
                        self.getAvailSpace()
                }
            } else {
                self.alertControllerMsg(msgStyle: UIAlertControllerStyle.alert,msgTitle: "Insufficient Network", msgBody: "Please connect to a Wifi network to download this file.", cancelLbl: "Cancel", actionLbl: "Retry", complete: {
                    self.downloadAndSort()
                })
            }
        })
    }
}

EDIT:

CellforRowAt code

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if let cell = tableView.dequeueReusableCell(withIdentifier: "downloadCell", for: indexPath) as? downloadCell {
        let currentFile = CurrentFiles[indexPath.row]
        cell.configureCell(currentFile: currentFile)
        return cell
    } else {
        return downloadCell()
    }
}

EDIT 2:

class downloadCell: UITableViewCell {

@IBOutlet weak var fileLbl: UILabel!
@IBOutlet weak var fileIcon: UIImageView!
@IBOutlet weak var pctLabel: UILabel!
@IBOutlet weak var additionalLbl: UILabel!
@IBOutlet weak var fileSize: UILabel!
@IBOutlet weak var progressView: UIProgressView!

var fileStatus = "NotInstalled"
func configureCell(currentFile: currentFiles) {

    fileLbl.text = currentFile.labelName
    fileSize.text = currentFile.fileSize
    let internalName = currentFile.internalName
    fileIcon.image = UIImage(named: "download")
    additionalLbl.text = "Updated: \(convertDateFormatter(date: currentFile.lastUpdate))"

    let fileExists = (readFromSharedFile(sharedFilename: internalName, fileExtension: currentFile.fileExtension))
    if fileExists == "Success" {
        //file has been downloaded on device
        let lastUpdateDate = UserDefaults(suiteName: applicationGroup)!.string(forKey: internalName)

        if lastUpdateDate != currentFile.lastUpdate {
                fileIcon.image =  UIImage(named: "download")
                fileStatus = "NeedsUpdate"
            } else {
                fileIcon.image = nil
                fileStatus = "Installed"
                additionalLbl.text = nil
            }
    } else {
        // not on device
        fileStatus = "NotInstalled"

    }
}
}

Upvotes: 2

Views: 1187

Answers (4)

Nate23VT
Nate23VT

Reputation: 423

On my view controller, I created a new dictionary to hold my file names and current progress defaulting to 0 and an array to hold the currently downloading files

var downloadProg = [String: Double]()
var currentDownloadNames = [String]()

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if let cell = tableView.dequeueReusableCell(withIdentifier: "downloadCell", for: indexPath) as? downloadCell {
        let currentFile = CurrentFiles[indexPath.row]
        cell.configureCell(currentFile: currentFile)
        if !(currentDownloadNames.contains(currentFile.labelName)) {
            cell.progressView.isHidden = true
            cell.pctLabel.isHidden = true
            cell.fileIcon.isHidden = false
        } else {
            cell.fileIcon.isHidden = true
            cell.progressView.isHidden = false
            cell.pctLabel.isHidden = false
        }
        return cell
    } else {
        return downloadCell()
    }
}

I now set the dictionary percentage in my .downloadProgress

                            downloadProg[cellName] = progress.fractionCompleted

and I modified the downloadCell to show the percentage:

let pct = downloadProg[currentFile.labelName]
    if (progressView.isHidden == false){
        progressView.setProgress(Float(pct!), animated: true)
        pctLabel.text = "\(String(format:"%g",round(pct!*100)))%"
    } 

Upvotes: 1

Sean Lintern
Sean Lintern

Reputation: 3141

It sounds like you need to reset the progress view in your prepareForReuse:

In the cell override:

override func prepareForReuse() {

}

This gets called when the cell is reused, which sounds like what is happening for yourself.

Upvotes: 0

iSwift
iSwift

Reputation: 314

Tick the cell.progressview hidden flag to true in inspector builder either this. or you have to print and check your hidden status for progressview.

Upvotes: 0

SergGr
SergGr

Reputation: 23788

We really need your code for cellForRowAtindex as well and a better description of the issue. How many cells fit the screen (is it around 12)? Is just progress view shown for every 12-th cell or does actual progress run in every 12th cell? If the progress view is just shown but is not updated, then the most obvious reason that comes to mind is that you forgot to hide progressView in cellForRowAtindex when the cell is being re-used after dequeue​Reusable​Cell(with​Identifier:​).

Upvotes: 0

Related Questions