BluGeni
BluGeni

Reputation: 3454

uiprogressview not finishing to 100% visually

I do not get what is going on here. I have a progress bar that gets almost complete but does not show it. If I were incrementing by .10 it would stop at .9 or so it looked visually and I can figure out how to fix it.

    float total = self.forms.count;

   float calc =  (float)self.progView.progress + (1 / total);
    self.progView.progress = calc;
    if (self.progView.progress == 1 )
    {

        sleep(2);
        self.progView.hidden = YES;
                self.progView.progress = 0;
    }

I know it goes into the if statement because it will sleep for 2 seconds like this enter image description here

edit:

hmm I took out the last 2 lines and it does seem to update the last part it must be an issue with a block I have that it is being called from?

Even with this method wrapped in dispatch_async(dispatch_get_main_queue() I still have the problem.

sleep is bad on the main thread:

here is my new working code:

if (self.progView.progress == 1 )
    {
        [NSTimer scheduledTimerWithTimeInterval:.5 target:self selector:@selector(removeProg) userInfo:nil repeats:NO];
    }

method

-(void)removeProg
{
    self.progView.hidden = YES;
    self.progView.progress = 0;
}

Upvotes: 1

Views: 436

Answers (1)

matt
matt

Reputation: 534893

It all has to do with how drawing works in iOS. It doesn't happen when you ask for it. It happens later! The interface is updated only we come to a "redraw moment". This can only happen after all your code has stopped running. All commands to update the interface are meaningless until then. When the "redraw moment" comes, all the accumulated commands to update the interface are executed. If multiple accumulated commands affect the same feature of the interface, only the last one counts.

So let's examine your code:

self.progView.progress = calc;
if (self.progView.progress == 1 )
{
   sleep(2);
   self.progView.hidden = YES;
   self.progView.progress = 0;
}

Let's say the progress was .9. Now you set the progress to calc and let's say calc is 1. But there is no redraw moment yet so the interface does not change. We still see the thermometer at .9. Your code continues to run, and you set the progress to 0. Now your code ends. Now there is redraw moment. So the thermometer jumps from .9 to 0 without ever being displayed at 1.

A simple parallel experiment is like this:

myView.backgroundColor = [UIColor greenColor];
sleep(2);
myView.backgroundColor = [UIColor redColor];

You'll never see the view become green, because when the redraw moment comes, the last command was to make it red, so that's what appears.

Technically, when the runtime sends you an event that starts your code running, a CATransaction is begun. When all your code finishes running and the runtime's original event completes, the CATransaction is "committed" and we go into a bunch of cleanup. This includes doing all accumulated drawing plus launching any requested animations.

Upvotes: 2

Related Questions