user623245
user623245

Reputation: 1

Change UILabel in loop

I want to change the UILabel after 2 sec in a loop. But current code change it to last value after loop finished.

- (IBAction) start:(id)sender{


   for (int i=0; i<3; i++) {
    NSString *tempStr = [[NSString alloc] initWithFormat:@"%s", @" "];

    int randomNumber = 1+ arc4random() %(3);

    if (randomNumber == 1) {
        tempStr = @"Red";
    }else if (randomNumber == 2) {
        tempStr = @"Blue";
    } else {
        tempStr = @"Green";
    }
       NSLog(@"log: %@ ", tempStr);
       labelsText.text = tempStr;
       [tempStr release];
        sleep(2);

    }
}

Upvotes: 0

Views: 1957

Answers (3)

Jim
Jim

Reputation: 73966

Don't use sleep() to perform actions after a delay, it blocks the whole thread. Use performSelector:withObject:afterDelay: instead. As you are probably running this on the main thread, sleep() will block any UI updates until after the whole loop has run, so the only thing you see is the last update. As a general rule of thumb, assume that the UI doesn't ever get updated until after the app has finished executing your method.

You shouldn't use %s as the format specifier for an NSString, that's the format specifier for a C string. You should use %@ instead. In fact, if all you are doing is initialising the string with an NSString literal, there's no need to use initWithFormat at all, you can just use the literal itself.

You've also got big memory problems. At the beginning of the loop, you allocate memory for an instance of NSString that is a single space. You then overwrite the pointer to this memory when you assign to tempStr again, meaning you leak the original allocation of memory. Build and Analyze will find problems like this for you. Then you release tempStr, but as the second assignment to this pointer variable was to an autoreleased NSString, the instance will be released one time too many when the autorelease pool gets drained, which will probably manifest itself as a crash that's impossible to debug a little later in the app.

I'd do something like this:

- (void)showRandomColourAfterDelay {
    static NSUInteger count = 0;
    switch (arc4random()%3) {
        case 0:
            labelsText.text = @"Red";
        case 1:
            labelsText.text = @"Blue";
        case 2:
            labelsText.text = @"Green";
    }
    count++;
    if (count >= 3) return;
    [self performSelector:@selector(showRandomColourAfterDelay) withObject:nil afterDelay:3];
}

In fact, I'd probable use an NSArray to hold the colour strings, but that would involve changes outside of a single method, so I've stuck with your hard-coding approach.

Upvotes: 0

Zaky German
Zaky German

Reputation: 14324

- (IBAction) start:(id)sender{
   for (int i=0; i<3; i++) {

    int randomNumber = 1+ arc4random() %(3);
    NSString *tempStr = @"";
    if (randomNumber == 1) {
        tempStr = @"Red";
    }else if (randomNumber == 2) {
        tempStr = @"Blue";
    } else {
        tempStr = @"Green";
    }
    [labelsText performSelector:@selector(setText:) withObject:tempStr afterDelay:i * 2]
       NSLog(@"log: %@ ", tempStr);
    }
}

Upvotes: 0

Vladimir
Vladimir

Reputation: 170859

Your code updates label to last value only as your function blocks main thread so UI cannot get updated. To solve that problem move your updating code to separate function and call it using performSelector:withObject:afterDelay: method. (or schedule calls using NSTimer)

Possible solution (you will also need to handle the case when user taps your button several times in a row, but that should not be too difficult):

- (IBAction) start:(id)sender{
    [self updateLabel];
}

- (void) updateLabel{
   static const NSString* allStrings[] = {@"Red", @"Blue", @"Green"};
   static int count = 0;

   int randomNumber = arc4random()%3;
   NSString *tempStr = allStrings[randomNumber];

   NSLog(@"log: %@ ", tempStr);
   labelsText.text = tempStr;

   ++count;
   if (count)
      [self performSelector:@selector(updateLabel) withObject:nil afterDelay:2.0];

}

Upvotes: 2

Related Questions