Say you’ve got an operation that takes a long time and you don’t want to block the main thread.

Here’s how you can add a spinner to show the user an update is happening.

Hook up the refresh button

Control drag the refresh button into your custom view.

Then just hook up as follows:


- (IBAction)refresh:(id)sender {

    // replace right bar button 'refresh' with spinner
    UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
    [spinner startAnimating];
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:spinner];

    // how we stop refresh from freezing the main UI thread
    dispatch_queue_t downloadQueue = dispatch_queue_create("flickr downloader", NULL);
    dispatch_async(downloadQueue, ^{
        NSArray *photos = [FlickrFetcher recentGeoreferencedPhotos];

        // do any UI stuff on the main UI thread
        dispatch_async(dispatch_get_main_queue(), ^{
            // put rightbar button back
            self.navigationItem.rightBarButtonItem = sender; // sender because that's the element that called us by clicking refresh
   = photos;



For the complete story on this demo checkout Lecture 10 52min mark of Paul Hegarty’s iPhone App Dev course.