PeterK
PeterK

Reputation: 4301

UIProgressView do not update in loop

I am loading a file and would like to show the progress in a UIProgressView. I can set the initial with:

[loadingProgressView setProgress: 0.00];

..in viewDidLoad this works perfectly.

The only thing I want to do then is to add 0.1 to the bar each loop but it does not update:

 while (eOF != 99999) {

    ...

    [loadingProgressView setProgress:loadingProgressView.progress + 0.10];

 }

I have checked around but not really found anything around just updating the bar each time I loop.

Anyone that can share some advice around this?

---UPDATE---

tried this without success:

while (eOF != 99999) {

    ...

    [loadingProgressView setProgress:loadingProgressView.progress + 0.10];
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate date]];

 }

Upvotes: 1

Views: 6206

Answers (5)

Maxim Lavrov
Maxim Lavrov

Reputation: 336

I guess that the proper way in this case is to use blocks and multithreading. Your code will look like this:

dispatch_queue_t myQueue = dispatch_queue_create("my queue", NULL);
dispatch_async(myQueue, ^
{
    while (eOF != 99999) {

        // ...
        // your code
        // ...

        dispatch_async(dispatch_get_main_queue(), ^{
            loadingProgressView.progress += 0.10;
        });
    }
});
dispatch_release(myQueue);

For more info see Paul Hegarty's lections here http://itunes.apple.com/itunes-u/ipad-iphone-application-development/id480479762 lecture 10, very clear explanation and tutorial.

Upvotes: 2

PeterK
PeterK

Reputation: 4301

MY FINAL SOLUTION

First, if this is the wrong way of closing this thread i do apologize!

After a lot of testing and investigation i finally did as follows to display my UIProgressView:

while (eOF != 99999) {

    ...

    [NSThread sleepForTimeInterval: 0.01];
    [self performSelectorOnMainThread: @selector(makeMyProgressBarMoving) withObject: nil waitUntilDone: NO];

 }



-(void)makeMyProgressBarMoving {
    float actual = [loadingProgressView progress];
    loadingProgressView.progress = actual + receivedData;
} 

...and now finally it works perfectly :-)

However, thanks for all help, i learned a lot out of this.

Upvotes: 3

jbat100
jbat100

Reputation: 16827

You are looping through your while loop blocking the main thread, UI elements will not be able to refresh until the main thread becomes available. The best way around this is to run this code in a background thread (making the UI call on the main thread).

Or (I'm not sure about this one, see this discussion) you let the main thread some breathing space by calling

NSDate* futureDate = [NSDate dateWithTimeInterval:0.001 sinceDate:[NSDate date]];
[[NSRunLoop currentRunLoop] runUntilDate:futureDate];

Upvotes: 11

Jeff Kelley
Jeff Kelley

Reputation: 19071

The UI updates as a part of the run loop, which won't happen during that while loop. You can get it to run by calling this:

[[NSRunLoop currentRunLoop] runUntilDate:[NSDate date]];

This forces the loop to update the UI, etc.

Upvotes: 4

Michael Dautermann
Michael Dautermann

Reputation: 89509

A couple things you could try.

First, check to see what your UIProgressView's current value is (before you increment it)

i.e.

float progress = loadingProgressView.progress;

[loadingProgressView setProgress: progress+0.10];

(set a breakpoint on that line to see if progress ever increments)

Secondly, force an update via:

[loadingProgressView setNeedsDisplay];

and see what happens then.

Upvotes: 0

Related Questions