Say you’ve got a long running process and you want to popup a spinner while your process is working. Here’s how you do it.

ViewController.h

#import <UIKit/UIKit.h>

@interface rcsViewController : UIViewController
@property (weak, nonatomic) IBOutlet UILabel *myLabel;
@property (weak, nonatomic) IBOutlet UIButton *myButton;
@end

ViewController.m

#import "rcsViewController.h"

@implementation rcsViewController
@synthesize myLabel;
@synthesize myButton;

- (IBAction)process:(id)sender {    
        
    // replace right bar button 'refresh' with spinner
    UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
    spinner.center = CGPointMake(160, 240);
    spinner.hidesWhenStopped = YES;
    [self.view addSubview:spinner];    
    [spinner startAnimating];
        
    // how we stop refresh from freezing the main UI thread
    dispatch_queue_t downloadQueue = dispatch_queue_create("downloader", NULL);
    dispatch_async(downloadQueue, ^{

        // do our long running process here
        [NSThread sleepForTimeInterval:10];
        
        // do any UI stuff on the main UI thread
        dispatch_async(dispatch_get_main_queue(), ^{
            self.myLabel.text = @"After!";
            [spinner stopAnimating];
        });
        
    });
    dispatch_release(downloadQueue);
}

- (void)viewDidLoad
{
    [super viewDidLoad];    
}

- (void)viewDidUnload
{
    [self setMyLabel:nil];
    [self setMyButton:nil];
    [super viewDidUnload];
}

@end

The magic happens when the users presses the button. Here we create our spinner, add it to our subview, and start it up.

    UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
    spinner.center = CGPointMake(160, 240);
    spinner.hidesWhenStopped = YES;
    [self.view addSubview:spinner];    
    [spinner startAnimating];

Once it’s going we create a separate thread to do our processing in, along with a call to the main UI thread when it’s done (which changes the label and stops the spinner).

 dispatch_queue_t downloadQueue = dispatch_queue_create("downloader", NULL);
    dispatch_async(downloadQueue, ^{

        // do our long running process here
        [NSThread sleepForTimeInterval:10];
        
        // do any UI stuff on the main UI thread
        dispatch_async(dispatch_get_main_queue(), ^{
            self.myLabel.text = @"After!";
            [spinner stopAnimating];
        });
        
    });

That’s it!

About these ads