4

I have a problem calculating progress for my UIProgressView. My float value has no effect on the progress. I tried to set progress manually it works fine but if I try to calculate it it doesn't work.

Here is my code :

- (void) initProgressbar {

   self.progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
   [self.progressView setFrame:CGRectMake(0, 0, SCREEN_WIDTH / 2, 10)];
   self.progressView.center = CGPointMake(SCREEN_WIDTH - 110, SCREEN_HEIGHT - 25);
   self.progressView.progress = 0.0;
   [self.view addSubview:self.progressView];
}

nbElementsSync and nbElementsToSync are global int properties and nbElementsSync is incremented by a loop before updateProgress method is being called.

MyController.h

@interface MyController : UIViewController {

   NSString *json;
   int nbElementsToSync;
   int nbElementsSync;

}

@property (nonatomic, strong) UIProgressView *progressView;

MyController.m

nbElementsSync = 0; // Nb elements synchronized
nbElementsToSync = [[json valueForKey:@"count"] intValue]; // Nb elements to synchronize

for (NSString* result in results) {

    nbElementsSync++;
    [self updateProgress];

}

And here is my method to set up the progress :

- (void) updateProgress {

   [self.progressView setProgress:((float)nbElementsSync / nbElementsToSync)];
   NSLog(@"percent : %f", ((float)nbElementsSync / nbElementsToSync));

}

Results of my NSLog :

percent : 0.003937
percent : 0.007874
percent : 0.011811
percent : 0.015748
percent : 0.019685
percent : 0.023622
...

Any idea to solve it ? Thanks in advance.

user3405644
  • 195
  • 1
  • 2
  • 11
  • can you show the code you have implemented in your loop and is nbElementsToSync changes with time? – channi Jan 19 '15 at 09:37
  • so what are you getting out of it? Make sure your array "results" count is same as of your "nbElementsToSync" – channi Jan 19 '15 at 10:09
  • Are you sure that you're not calling updateProgress on another thread? You can only update the UI from the main thread. Try logging this and if it is zero then that's a problem NSLog(@"%@", @([NSThread isMainThread])) – SomeGuy Jan 19 '15 at 10:11
  • NSLog(@"%@", @([NSThread isMainThread])) returns always 1 – user3405644 Jan 19 '15 at 13:42

1 Answers1

3

Have you tried doing the loop in a background process, not to block the UI updates :

MyController.m

Call this where you need to:

[self performSelectorInBackground:@selector(syncInBackground) withObject:nil];

Then

- (void)syncInBackground
{
    int nbElementsSync = 0; // Nb elements synchronized
    int nbElementsToSync = [[json valueForKey:@"count"] intValue]; // Nb elements to synchronize

    for (NSString* result in results) {
        nbElementsSync++;

        float percent = (float)nbElementsSync / nbElementsToSync;

        [self performSelectorOnMainThread:@selector(updateProgress:) withObject:[NSNumber numberWithFloat:percent] waitUntilDone:NO];
    }   
}

- (void) updateProgress:(NSNumber *)percent {

    [self.progressView setProgress:percent.floatValue];
}
Niko
  • 3,412
  • 26
  • 35
  • No I haven't. My synchronization have to be in the main thread not in the background. I don't understand why my progress is not visible on the UIProgressView when I could NSLog percent and have returned values between 0.0 and 1.0 ... – user3405644 Jan 19 '15 at 13:46
  • 1
    When you run a heavy process on the main thread (eg loops) you are blocking the UI and it won't be able to update. You should do your loop on the background thread and update the progressView on the main Thread – Niko Jan 19 '15 at 15:02
  • OK Niko but my loops are executed in result of multiple NSURL Connection so it would be complex to implement it as a background thread... – user3405644 Jan 19 '15 at 15:08
  • If I'm not wrong according to your code, you need 2 elements to calculate percentage : results and nbElementsToSync. First idea : create an object that will have all elements you need, then give it to withObject parameter [self performSelectorInBackground:@selector(syncInBackground) withObject:myObjectWithElements]; If results or nbElementsToSync values will change, you'll have to find your way to sync on backgound – Niko Jan 19 '15 at 15:23