0

Hi I am implementing a 'save image to library' feature as seen in the code snippet below. Basically, the photo saving is triggered when a user touches an image on the page.

TouchImageView *tiv = [[TouchImageView  alloc]initWithFrame:blockFrame];
        [tiv setCompletionHandler:^(NSString *imageUrl){
            //Spinner should start after user clicks on an image
            MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES];
            hud.labelText = @"Saving photo to library";

            //trigger method to save image to library
            [self saveImageToLibrary];

        }];


-(void) saveImageToLibrary
{
    //convert url to uiimage
    UIImage *selectedImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]]]; 

    //Save image to album
    ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];  
    // Request to save the image to camera roll  
    [library writeImageToSavedPhotosAlbum:[selectedImage CGImage] orientation:(ALAssetOrientation)[selectedImage imageOrientation] completionBlock:^(NSURL *assetURL, NSError *error){  

        [MBProgressHUD hideHUDForView:self.navigationController.view animated:YES];

        if (error) {  
            NSLog(@"error");  
        } else {  
            NSLog(@"url %@", assetURL);  
            //Trigger get photo from library function
            self.imgPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
            [self presentModalViewController:self.imgPicker animated:YES];

        }  

    }];  
    [library release];     
}

The issue is that the HUD spinner does not appear (after a lag time of 3-4 seconds), my suspicion is that the 'writeImageToSavedPhotosAlbum:' is synchronous and locked the process from displaying the HUD spinner. Is this right? How do I resolve the lag in spinner display?

Zhen
  • 12,361
  • 38
  • 122
  • 199

1 Answers1

2

Yes, that is correct. Replace the call

 [self saveImageToLibrary];

by

[self performSelector:@selector(saveImageToLibrary) withObject:nil afterDelay:0];

so that the HUD gets a chance to show itself before you save.

edsko
  • 1,628
  • 12
  • 19
  • Thanks, this works! Just to clarify, what does this performSelector do exactly? Thanks! – Zhen Oct 21 '11 at 10:19
  • 2
    Your app executes a "runloop", basically a top-level never-terminating while-loop. At the start of each iteration through the loop the UI gets updated. When you call a method to change the UI, the UI will not actually be changed until the next iteration of the loop. So when you execute something long-running (like your save operation) that request does not get executed until your save operation completes, which defeats the purpose of the HUD :) I explain this in a bit more detail at http://stackoverflow.com/questions/7452925/threads-and-autoreleasepool-questions/7710576#7710576. – edsko Oct 21 '11 at 10:39
  • 1
    Oh, and the the performSelector says: "call this method in the next iteration of the runloop" -- so that will execute after the HUD is shown. – edsko Oct 21 '11 at 11:26
  • Thanks! That clears things up for me :) Appreciate your help here – Zhen Oct 21 '11 at 13:57