Origamiguy
Origamiguy

Reputation: 1324

Execute code /after/ UIImagePicker is dismissed

I have a simple iPhone application.
I display a UIImagePicker, and let the user select an image.
I then execute some code on the image, and want this code to execute after the UIImagePicker has been dismissed.

EDIT: updated code, problem remains:

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    NSData* data = UIImagePNGRepresentation([info objectForKey:@"UIImagePickerControllerOriginalImage"]);
    [[picker parentViewController] dismissModalViewControllerAnimated:TRUE];
    [self executeSomeCode: data];
}

However, when I run the code, it hangs on the UIImagePicker to run my code, and then the UIImagePicker is visually dismissed after said code has executed.

Any ideas?

Upvotes: 0

Views: 973

Answers (4)

Rafael Nobre
Rafael Nobre

Reputation: 5131

I don't think you are hanging where you think you are. UIImagePNGRepresentation takes quite some time to perform as far as I know (UIImageJPEGRepresentation is much faster, if you don't mind not being lossless). You could pass the dictionary into your method and obtain the NSData you need in there.

Your second problem is that your code is synchronous, no matter how soon you tell your controller to dismiss, it will wait your long code to run. To schedule your heavy code on the next run loop iteration and let the controller be dismissed, use a 0ms delay to perform it.

I would change your code to this:

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    [[picker parentViewController] dismissModalViewControllerAnimated:YES];
    [self performSelector:@selector(executeSomeCode:) withObject:info afterDelay:0.0f];
}

Upvotes: 0

djromero
djromero

Reputation: 19641

It shouldn't be necessary to use a background method, but you can try this approach:

- (void)_processImage:(UIImage*)image 
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    // convert to PNG data here, etc.
    // this is background, remember to manipulate UI in main thread
    // Example: [self.anImageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];
    [pool release];
}

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    [[picker parentViewController] dismissModalViewControllerAnimated:YES];
    UIImage *picked = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
    [self performSelectorInBackground:@selector(_processImage:) withObject:[[picked retain] autorelease]];
}

Upvotes: 1

thelaws
thelaws

Reputation: 8001

I realize this isn't the most graceful of answers. I've had similar problems before (trying to do visual things in viewDidAppear that wasn't working). I found that by calling performSelector:withObject:afterDelay: caused my visual effects to be seen.

So in your case it would be:

[self performSelector:@selector(executeSomeCode:) withObject:data afterDelay:0];

I have no idea if this will work for you (or why it worked for me).

Upvotes: 1

Aaron Saunders
Aaron Saunders

Reputation: 33345

http://developer.apple.com/iphone/library/documentation/uikit/reference/UIImagePickerControllerDelegate_Protocol/UIImagePickerControllerDelegate/UIImagePickerControllerDelegate.html

I believe your call was deprecated in iOS3

You might try

(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info

and the get the data from the image before dismissing the viewController

NSData *data = UIImageJPEGRepresentation( [info objectForKey:@"UIImagePickerControllerOriginalImage"] , 1.0);
[self dismissModalViewControllerAnimated:TRUE];
[self executeSomeCode:img];

Upvotes: 0

Related Questions