简体   繁体   中英

Swift progress bar completedUnitCount and totalUnitCount

I don't know if I understood completedUnitCount and totalUnitCount well, I will describe you my problem.

Declaration of progress bar:

@IBOutlet weak var progressBar: UIProgressView!
let progress = Progress(totalUnitCount: 5)

This '5' makes no sense but I put it just to test filling of progress bar.

I want to when I click on button below, to make that button disappear and make progressbar appear on button's place. By default, progressbar is hidden and button is not.
It works well, but problem is because I want to dismiss current VC when completedUnitCount is equal to totalUnitCount.
When I select 5 cardsets, my completedUnitCount is 5 so it is equal to totalUnitCount. It starts to fill progressBar and dismisses VC before it is fulfilled.
Here is my code, I think you don't have to pay attention on Realm stuff, and cardsets in just an array loaded from API and selected ones should be posted in realmTable and it works OK:

@IBAction func btnDownload(_ sender: Any) {
    print("button download pressed")

    let realm = try! Realm()

    for id in cardsetIds {
        for cardset in cardsets {
            if id == cardset.id && cardset.cards != "0" {
                let newSet = CardsetTable()
                newSet.cards = cardset.cards
                newSet.size = cardset.size
                newSet.title = cardset.title
                newSet.id = cardset.id

                try? realm.write { realm.add(newSet) }

                btnDownload.isHidden = true
                progressBar.isHidden = false

                progress.completedUnitCount += 1
                let progressFloat = Float(self.progress.fractionCompleted)

                self.progressBar.setProgress(progressFloat, animated: true)
            }
        }
    }
    if progress.completedUnitCount == progress.totalUnitCount {

        self.dismiss(animated: true, completion: nil)
    }
}

Because the progress bar animates the changes it takes time to reach the end of the progress bar after you call

self.progressBar.setProgress(progressFloat, animated: true)

The common practice is to delay the processing of related animation (that should be done after progress bar completed its animation). My experience says that most of the iOS animations take 0.3 seconds, so just delay what you need:

if progress.completedUnitCount >= progress.totalUnitCount {
    delay(0.3) { // delay to let progress bar to complete the animation
        self.dismiss(animated: true, completion: nil)
    }
}


/// Delays given callback invocation 
///
/// - Parameters:
///   - delay: the delay in seconds
///   - callback: the callback to invoke after 'delay' seconds
func delay(_ delay: TimeInterval, callback: @escaping ()->()) {
    let delay = delay * Double(NSEC_PER_SEC)
    let popTime = DispatchTime.now() + Double(Int64(delay)) / Double(NSEC_PER_SEC);
    DispatchQueue.main.asyncAfter(deadline: popTime, execute: {
        callback()
    })
}

I just tested your code without the realm part, and it worked for me. I believe the problem is that your progress.completedUnitCount never reaches or it goes larger than the expected progress.totalUnitCount , probably because of the if statement and the number of cards in your loop.

Try changing the if statement to:

if progress.completedUnitCount >= progress.totalUnitCount {
    self.dismiss(animated: true, completion: nil)
}

If that does not work, then the value of progress.completedUnitCount never reaches the progress.totalUnitCount .

for calculate the progress bar to fit any number you want to add: for example you have 10 questions and user answer them. you have to check how many questions you have and user in which questions: you can use this logic to calculate the progress bar for example :

func getProgress() -> Float{
    return Float(questionsNumber + 1) / Float(quize.count)
}

here (quize.count) is the number of the questions we have
and which mean (total questions number). and the (questionsNumber) is user in which questions. so to you fit your progress bar your 1000 card of the total card number and you have to make another variable to check user in which card and the result must in float because the progress bar value is between 0 to 1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM