UIProgressBar isn't updated in loop

81 Views Asked by At

This question has been asked before, but the answers aren't working. I know that (correct me if I'm wrong) the main thread updates the UI, so we need to call the main thread in the loop. I'm trying this and the progress bar only updates at the end of the loop (so goes from 0% to 100%)

here is my code

.h

@interface ViewController : UIViewController <UITextFieldDelegate> {
IBOutlet UIProgressView *progressBar;
float progressBarPercentage;
}
-(IBAction)button:(id)sender;

@end

.m

-(IBAction)button:(id)sender{

for (int z=0; z < 9; z++){

//do stuff

float progressBarPercentage = (1.0 / 9.0 * (z + 1));
        [self performSelectorOnMainThread:@selector(makeMyProgressBarMove) withObject:nil waitUntilDone:NO];

}

}

-(void)makeMyProgressBarMove{

    [progressBar setProgress:progressBarPercentage animated:YES];
     }

When running in debug mode, I've noticed when it gets to the line [self performSelectorOnMainThread:@selector(makeMyProgressBarMove) withObject:nil waitUntilDone:NO]; it just restarts the loop without going to 1makeMyProgressBarMove:`

Also, the //do stuff part isn't short, it actually takes 5s to run the code when the button is pressed, so it's not like it's updating so fast I can't see it.

Thank you, and just let me know if more information is needed, I'm still a beginner

2

There are 2 best solutions below

5
On BEST ANSWER

You need to "Do Stuff" on another thread also, otherwise it will still block your main thread. Note that performSelectorOnMainThread has no use if you're already on the main thread.

Using libdispatch because it's much easier:

-(IBAction)button:(id)sender{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        for (int z=0; z < 9; z++)
        {
            //do stuff

            float progressBarPercentage = (1.0 / 9.0 * (z + 1));

            dispatch_async(dispatch_get_main_queue(), ^{
                [progressBar setProgress:progressBarPercentage animated:YES];
            });
        }
    });
}
1
On

now try this

 -(IBAction)button:(id)sender{

    for (int z=0; z < 9; z++){

    //do stuff

    float progressBarPercentage = (1.0 / 9.0 * (z + 1));
            [self performSelectorOnMainThread:@selector(makeMyProgressBarMove) withObject:nil waitUntilDone:YES];

    }

    }

    -(void)makeMyProgressBarMove{

        [progressBar setProgress:progressBarPercentage animated:YES];
         }