UIProgressView not updating progress

44 Views Asked by At

My app has an import feature which takes String data coming from another ViewController and passing it on using an unwind segue. In the destination ViewController there's a ProgressView added to an AlertView that should update for every imported component of the String, but the progress bar never updates.

Here's the destination ViewController:

import UIKit

class MoviesViewController: UITableViewController {

    var progressView: UIProgressView!
    [...]

    @IBAction func addImportedMovies(_ segue: UIStoryboardSegue) {
        if let importViewController = segue.source as? ImportViewController, let importedMovielist = importViewController.movies {
            importedMovies = importedMovielist.reversed()
            if importedMovies != [] {
                self.parent?.dismiss(animated: true, completion: nil)
                let alertView = UIAlertController(title: "Please wait", message: "Data is being processed...", preferredStyle: .alert)
                present(alertView, animated: true, completion: { [self] in
                    let margin:CGFloat = 8.0
                    let rect = CGRect(x: margin, y: 72.0, width: alertView.view.frame.width - margin * 2.0 , height: 2.0)
                    progressView = UIProgressView(frame: rect)
                    progressView.tintColor = view.tintColor
                    alertView.view.addSubview(progressView)
                    progressView.isHidden = false
                    DispatchQueue.main.async { [self] in
                        progressView.progress = 0.0/Float(importedMovies.count)
                        for (i, movie) in importedMovies.enumerated() {
                            progressView.progress = Float(i+1)/Float(importedMovies.count)
                            print(progressView.progress)
                            [...updating DataSource and TableView]
                        }
                        [...]
                        alertView.dismiss(animated: true, completion: nil)
                        importedMovies = []
                    }
                })
            }
        }
    }
}

I tried using DispatchQueue.global, moving the code to ViewWillAppear and various other changes I've seen mentioned in similar threads but had no success.

Here's what the Alert shows during the for loop: https://i.stack.imgur.com/Uo694.jpg

1

There are 1 best solutions below

1
TheHungryCub On

UI updates will be performed on the main thread.

Try this:

@IBAction func addImportedMovies(_ segue: UIStoryboardSegue) {
    if let importViewController = segue.source as? ImportViewController, let importedMovielist = importViewController.movies {
        importedMovies = importedMovielist.reversed()

        if !importedMovies.isEmpty {
            self.parent?.dismiss(animated: true, completion: nil)

            let alertView = UIAlertController(title: "Please wait", message: "Data is being processed...", preferredStyle: .alert)

            let progressView = UIProgressView(progressViewStyle: .default)
            alertView.view.addSubview(progressView)

            present(alertView, animated: true, completion: { [self] in
                DispatchQueue.main.async { [self] in
                    progressView.progress = 0.0

                    for (i, movie) in importedMovies.enumerated() {
                        progressView.progress = Float(i + 1) / Float(importedMovies.count)
                        print(progressView.progress)
                    }

                    alertView.dismiss(animated: true, completion: nil)
                    importedMovies = []
                }
            })
        }
    }
}