0

I'm trying to update a UILabel within a "while loop" but it is not changing the UILabel text. I know that it is shown at the end of the current run loop cycle at the main thread as usual for iOS. But how can solve this problem ( the ftp.AsyncFinished function is provided by external chilkat ftp module) :

The data is updated every second. I searched this forum and in Apple's documentation, but I could not figure out the correct way to update a UILabel within a "while loop" on the main thread. What can I use instead of a while loop, that allows the main thread to update the UILabel.

while (ftp.AsyncFinished != YES) {
    // here is the code getting data from the cilkat FTP module stored in PercentOfFile and MinutesRemaining
    NSString *content =[[NSString alloc] initWithFormat:@"%.0f%% done%.0fmin left",PercentOfFile,MinutesRemaining ];
    [LabelProgress setText:content];
}
Jan
  • 47
  • 1
  • 9
  • 4
    http://stackoverflow.com/questions/6363828/updating-uilabel-in-the-middle-of-a-for-loop – Habib May 02 '12 at 09:34
  • @Habbib.OSU Note that the `runMode:beforeDate:` approach is quite dangerous. I've added a better solution to that question based on GCD. – Rob Napier May 02 '12 at 13:16

4 Answers4

4

In order for the UI to update at all, the main thread's run loop has to complete. That means your method (if called on the main thread), must return before any UI updates occur. All updates are then coalesced and the UI is redrawn.

See What is the most robust way to force a UIView to redraw? for more background.

Your while loop is incorrectly designed for an asynchronous update. You should not be fetching async data in the middle of a while loop. You should be registering for a callback of some kind (generally by setting yourself as delegate) and then just waiting for the system to call you.

Community
  • 1
  • 1
Rob Napier
  • 286,113
  • 34
  • 456
  • 610
1

You will need to call your upload progress in another thread and register for call backs. Create a custom class that inherits from CkoFTP2Progress which has this method:

- (void)PercentDone: (NSNumber *)pctDone abort:(BOOL *)abort;

Assuming you have a CkoFTp2 object named "ftp" and your custom class named "UploadProgress", register for callbacks:

[self.ftp setEventCallbackObject:self.uploadProgress];
Ngoan Nguyen
  • 747
  • 2
  • 9
  • 19
0

You could move the while loop to a background thread and call setText from there with performSelectorOnMainThread.

  • 1
    ...or simply run a timer in the main thread that updates the label. – Till May 02 '12 at 09:41
  • Moving the while loop to a background treat is not possible due to the connection to a external FTP module. How can i do this with a timer ? – Jan May 02 '12 at 11:06
0
// update your UILabel here
// ...

// Delay execution of long-running task so that update of UILabel can be performed
dispatch_after( dispatch_time( DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC ), dispatch_get_main_queue(), ^{
     // long-running task 
     // ..
});
John
  • 8,468
  • 5
  • 36
  • 61