3

In a buttonClicked method, I want to set the color of the text in a UILabel to black, wait three seconds, then set the color to green. However, the label never turns black. The method waits three seconds, then the UILabel text turns green. I thought that using performSelectorOnMainThread would solve this problem, but it hasn't. The code is below. Many thanks in advance, and apologies if I'm missing something obvious.

Jon R.

-(void) buttonClicked: (id) sender
{
    // (UILabel *) letterLabel is instance variable of TestProgramDelegate

    [letterlabel performSelectorOnMainThread:@selector(setTextColor:) withObject:[UIColor blackColor] waitUntilDone:YES];

    [NSThread sleepForTimeInterval:3];

    [letterLabel performSelectorOnMainThread:@selector(setTextColor:) withObject: [UIColor greenColor] waitUntilDone:YES];
}
Michael Dautermann
  • 88,797
  • 17
  • 166
  • 215
Jonathan Rachlin
  • 361
  • 3
  • 16

2 Answers2

2

Your method is changing the color synchronously twice. All of that code executes on the main thread.

// run on main thread
[letterlabel performSelectorOnMainThread:@selector(setTextColor:) withObject:[UIColor blackColor] waitUntilDone:YES];

// buttonClicked: called on mainThread so this is on main thread
[NSThread sleepForTimeInterval:3];

// also on main thread ...
[letterLabel performSelectorOnMainThread:@selector(setTextColor:) withObject: [UIColor greenColor] waitUntilDone:YES];

The UI main thread is looping and looking for code to fire based on things like button clicks. Once the click is detected, your method executes, sets the color, waits three seconds and then sets the color again before the UI main loop can redraw. Since the UI doesn't redraw in between, you never see the first one.

If you want to do that, you'll need to set the color then on a background thread, wait three seconds and then call back to the main thread to update the UI.

This is a related post:

GCD, Threads, Program Flow and UI Updating

Community
  • 1
  • 1
bryanmac
  • 38,941
  • 11
  • 91
  • 99
0

The - (void)buttonClicked:(id)sender will be called on the main thread so it's confusing why you are using [letterlabel performSelectorOnMainThread:@selector(setTextColor:) withObject:[UIColor blackColor] waitUntilDone:YES]; when the context is already the main thread.

[letterlabel setBackgroundColor:[UIColor blackColor]]; should be all you need to call when the button is pressed.

You could use an NSTimer or local notification callback to change the color to green. It is generally not a good idea to put the main thread to sleep in your application.

Hope that helps!

TrevorL
  • 495
  • 2
  • 7