1

I have the UIBarButtonItem (configurated in interface builder). If a user click this button, the "heavy process" will be started and for better user experience I want to change this button with (UIActivityIndicatorView). I do it in the following way:

    self.indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];   
    indicator.hidesWhenStopped = YES;
    [self.heavyBarButton initWithCustomView:self.indicator];

    [self.indicator startAnimating];

    [NSThread detachNewThreadSelector:@selector(animateHeavyProcess) toTarget:self withObject:nil];

animateHeavyProcess:

     [self heavyProcess];
     [self.indicator stopAnimating];
     UIBarButtonItem *originalButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"maximize.png"] style:UIBarButtonItemStylePlain target:self action:@selector(startProcessClick:)];
     self.heavyBarButton = originalButton;
     [originalButton release];

What happens: after a user clicks the BarButton animation will be started and after processing button disappears. However, I want that the original button will be shown again.

Le_Coeur
  • 1,521
  • 5
  • 28
  • 44

3 Answers3

0

what if you use Grand Central Dispatch for the heavy process? I would think it's more convenient. But remember that you can not use any of the UI in that block. Here is an example: iphone ios running in separate thread

Community
  • 1
  • 1
Adrian Ancuta
  • 1,036
  • 9
  • 16
0

You should not be doing UI updates in a secondary thread; calls to UIKit should be on the main thread.

You can split out the UI updating part of your code:

- (void)restoreBarButtonItem
{
  [self.indicator stopAnimating];
  UIBarButtonItem *originalButton = [[UIBarButtonItem alloc] 
     initWithImage:[UIImage imageNamed:@"maximize.png"]
     style:UIBarButtonItemStylePlain
     target:self
     action:@selector(startProcessClick:)];
  self.heavyBarButton = originalButton;
  [originalButton release];
}

And then in your heavy process (running on the secondary thread) just call this new UI update method on the main thread:

- (void)animateHeavyProcess
{
  [self heavyProcess];
  [self performSelectorOnMainThread:@selector(restoreBarButtonItem:)
    withObject:nil
    waitUntilDone:NO];
}
gregheo
  • 4,182
  • 2
  • 23
  • 22
-1

You should use UIToolbar's setItems:animated: method to replace buttons.

greenhorn
  • 1,097
  • 6
  • 10