Fix for Troublesome User Interface (UI) Updates

Here’s a quick tip if run into the problem of requesting a UI update (changing label text, starting/stopping spinner) that just don’t seem to take place. This is a simple workaround and isn’t replacement if you need multiple threads given an unresponsive UI due to other time intensive tasks (such as network requests).

As an example, I often display some type of animation sequence while an application is loading, a spinner, rotating label, etc. I set this up inside the applicationDidFinishLaunching method. However, more often that not I run into problems with the display not properly updating, to get around this, I’ll will write something such as this:

UI Update Fix #1
// Take care of any other startup
- (void)startApp
{
  // Finish any other loading details
  ...
}
 
// Application loading
- (void)applicationDidFinishLaunching:(UIApplication *)application 
{
  // Define UI element here to indicate the app is loading
  ...
 
  // Give the UI a chance to update
  [self performSelector:@selector(startApp) withObject:nil afterDelay:.2];
...
}
UI Update Fix #2

You can apply this same idea directly to buttons, labels etc if you run into problems with controls not updating. For example, let’s say you have code similar to the following:

1
2
3
4
5
6
7
8
// Define a label
UILabel *textMsg = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 150, 30)];
textMsg.text = "@Label message here";
 
...
 
// At some point later, update the text
textMsg.text = @"New label message";

If you have problems with the UI not updating, replace line 7 above with this code:

[textMsg performSelector:@selector(setText:) 
    withObject:@"New label message" afterDelay:.2];

As I said earlier, these are not recommendations for fixing a sluggish UI if you have a lot of other activities in progress (you should look into threading in that case). However, with that said, I’ve found that a few performSelector calls sprinkled about judiciously can work wonders for a UI that isn’t cooperating.

  1. > I’ve found that a few performSelector calls sprinkled about judiciously
    > can work wonders for a UI that isn’t cooperating.

    I couldn’t agree more. I have run into similar problems and this saved my life over and over again. Also, note that using an afterDelay of 0 will simply execute the code once the next UI event loop starts (very similar to using callLater() in Adobe Flex/AIR)

  2. Hi John

    Can you use performSelector when you are in the main thread. I use it a lot when I am using procedures using NSInvocationOperation.

    Another tip which I would like to give. You can have a Default.png in your application and that will get loaded 1st when you start your application. This will avoid your screen looking black.

    Thanks
    Imthiaz

Comments are closed.