elevate
elevate

Reputation: 147

Progress Bar on forEach loop in swift

How would I measure the progress of a forEach loop and display it in a progress bar? I will be rotating vertical images to make them horizontal. The number of images to be converted will be different every time.

Here is what I am doing to convert the images which works fine, I just need a way to display progress to the user:

func rotateandSave(files: [URL]) {
    files.forEach { file in
        let path = file
        let image = NSImage(contentsOf: path)
        let rotatedImage = image?.rotated(by: rotateAngle)
        saveImage(image: rotatedImage!, destination: path)
    }
}

Upvotes: 1

Views: 1162

Answers (3)

wades
wades

Reputation: 292

Do this:

func rotateandSave(files: [URL]) {
DispatchQueue.global(qos: .utility).async {
    files.forEach { file in
        let path = file
        let image = NSImage(contentsOf: path)
        let rotatedImage = image?.imageRotated(by: 90)
        saveImage(image: rotatedImage!, destination: path)
        DispatchQueue.main.async {
            self.progressBar.increment(by: 1)
        }
    }
}

Upvotes: 1

Kishan Bhatiya
Kishan Bhatiya

Reputation: 2368

You can use ProgressView to display progress bar. You can add it to your controller as follow:

@IBOutlet weak var progressView: UIProgressView!
override func viewDidLoad() {
        super.viewDidLoad()
        progressView.progress = 0.0
} 

func rotateandSave(files: [URL]) {

    var numberOfFile = files.count
    var fileCounter = 0
    files.forEach { file in
        let path = file
        let image = NSImage(contentsOf: path)
        let rotatedImage = image?.rotated(by: rotateAngle)
        saveImage(image: rotatedImage!, destination: path)
        fileCounter + =1
        let progress = (Double(fileCounter)/Double(numberOfFile))
        progressView.setProgress(progress, animated: true)
    }
}

when your progressView's progress reach to maximum at this point you can perform your own action

Upvotes: 0

vball
vball

Reputation: 389

You can use a ProgressView for a simple progress bar. You add it to a view controller like any other view (as an @IBOutlet weak var). In viewDidLoad() set the progress to 0 so the bar starts empty.

A ProgressView's progress is set on a range of 0.0-1.0, with the option to be animated (I assume you want this). To update the ProgressView you can modify your existing function:

@IBOutlet weak var progressView: UIProgressView!
...    
func rotateandSave(files: [URL]) {
    let numFiles = files.count
    let fileNum = 0
    files.forEach { file in
        let path = file
        let image = NSImage(contentsOf: path)
        let rotatedImage = image?.rotated(by: rotateAngle)
        saveImage(image: rotatedImage!, destination: path)
        progressBar.setProgress(Double(fileNum)/Double(numFiles), true)
        fileNum += 1
    }
}

Upvotes: 0

Related Questions