dismissviewcontrolleranimated completion not calling completion on uiimagepickercontroller - iphone

This is the code I have:
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[picker dismissViewControllerAnimated:YES completion:^(void){
NSLog(#"Test");
}];
}
It dismisses the modal view controller, but doesn't call the completion argument. Am i doing something wrong?

void completion handlers are filled with a simple ^{, I've never seen your syntax before....
[picker dismissViewControllerAnimated:YES completion:^{
NSLog(#"Test");
}];
The only possible explanation I can come up with is that your image picker is being dismissed by some other means, and that you are not it's delegate (therefore you would not receive the didFinishPickingMediaWithInfo message). Another possibility could be a failure within the SDK at the time. I know from running a quick example project, that the completion block fires as expected in both syntactical models.

Related

ios custom takePicture button

I want my custom button to take a picture using UIImagePickerController and to save it in my device.
I can save the picture in the device using the default camera controls, although when i turn them off and start using my custom button it doesn't do the job.
- (IBAction)takePhoto:(id)sender {
[picker takePicture];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *chosenImage = info[UIImagePickerControllerEditedImage];
self.imageView.image = chosenImage;
UIImageWriteToSavedPhotosAlbum(chosenImage, nil, nil, nil);
[picker dismissViewControllerAnimated:YES completion:nil];
}
didFinishPickingMediaWithInfo is being called but the picture isn't being saved.
How can i achieve this?
I did something similar and used this tutorial to get be started. Have a look.
http://www.musicalgeometry.com/?p=821

UIImagePickerController didFinishPickingMediaWithInfo delegate calling is delayed?

I am new to iphone development.I am implementing the UIImagePickerController in my application .When didFinishPickingMediaWithInfo delegate is called that is when choose button is clicked its having some delay .My code is as follows
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
LGViewHUD* hud = [LGViewHUD defaultHUD];
hud.activityIndicatorOn=YES;
hud.bottomText=#"Login..";
[hud showInView:picker.view];
[self performSelectorInBackground:#selector(pickerFunction:) withObject:info];
}
- (void) pickerFunction :(NSDictionary *)info
{
profilePicture.image = [info objectForKey:#"UIImagePickerControllerEditedImage"];
[imgPicker dismissModalViewControllerAnimated:YES];
}
I am trying to bring a hud on choose button action but it comes only after some delay.Can any one suggest me a methods for this implementation.
Thanks in advance..
I don't think there is anything to do about it.
I've had the problem myself, and it seems that the lag is coming from UIImagePickerController calling the delegate method "didFinishPickingMediaWithInfo". Once it gets to that method, everything runs quickly. It doesn't matter what code you put into "didFinishPickingMediaWithInfo". The lag time happens BEFORE that method is even called.
I even tried this, which does nothing except dismiss the controller.
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[self dismissModalViewControllerAnimated:YES];
}
and it still took a few seconds do dismiss the UIImagePickerController.
I had a similar delay occurring with this delegate. Turns out the didFinishPickingMediaWithInfo isn't called until the image/video is compressed, which can take a few seconds depending on what it is.

[picker dismissModalViewControllerAnimated:YES]; not working

I am using
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
}
for imagepicker
and using
[picker dismissModalViewControllerAnimated:YES];
in iPad to dismiss the picker.
also i tried using
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker;{
[picker dismissModalViewControllerAnimated:YES];
}
to dismiss the picker once it done the work.
BUt its not dimissing it. when i tap anywhere in the screen, than only it gets dismiss.
What i am doing wrong to dismiss the imagepicker?
Many thnkas
The view controller that should call dismissModalViewControllerAnimated: should be the same one that called presentModalViewController:animated:
May be you must not have set delegate of picker.Try this:-
picker.delegate = self;

Why won't dismissmodalviewcontrolleranimated dismiss UIImagePickerController immediately on ios5?

I have a UITableViewController that pops up a UIImagePickerController, user takes a pic, hits the Use button, Picker dismisses to show a custom thumbnail spinner while the image is being processed, then the spinner is replaced by the actual thumbnail at the end of processing.
At least that's how it worked in iOS4. Now with iOS5 it just sits there processing until it's finished, and then everything works correctly. But I want that spinner in there so the user knows something's happening, otherwise it looks like it just hung.
So I have this:
- (void) actionSheet: (UIActionSheet *)actionSheet didDismissWithButtonIndex (NSInteger)buttonIndex {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = NO;
// yada, yada, yada
[self presentModalViewController:picker animated:YES];
[picker release];
}
And then this gets called when the user picks "Use":
- (void) imagePickerController: (UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[self dismissModalViewControllerAnimated:YES];
[self performSelectorOnMainThread:#selector(processImage:) withObject:info waitUntilDone:NO];
animate = true;
}
And then this gets called to perform the processing while the thumbnail is spinning:
- (void) processImage:(NSDictionary *)info
{
UIImage *image = nil;
NSString* mediaType = [info objectForKey:UIImagePickerControllerMediaType];
// processing of image
animate = false;
[activityImageView stopAnimating];
[activityImageView release];
[self.tableView reloadData];
}
Like I said, it worked perfectly with iOS4, but with iOS5, no such luck. So what's the deal? The image picker gets dismissed eventually, so why doesn't it get dismissed immediately?
I'm not sure why there's a disparity between iOS4 & iOS5 on this point. But your description of the UI hanging is fairly consistent with the code you've shown. The perform selector on main thread is doing just that, performing the selector on the main thread, which is the thread you're calling from. Because of this setting waitUntilDone: to NO is meaningless since it's not being sent to another thread it's simply running in order. You would probably get the results you want just from swapping the order, like So:
[self dismissModalViewControllerAnimated:YES];
animate = true;
[self performSelectorOnMainThread:#selector(processImage:) withObject:info waitUntilDone:NO];
But please note that this would be risky at best, since I assume // processing of image contains no concurrency. I prefer blocks for concurrency. And on top of that I like nested blocks to make the concurrency easy to follow, for example:
-(void)doSomeStuffInBackground{
// Prepare for background stuff
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// Do background stuff
dispatch_async(dispatch_get_main_queue(), ^{
// Update UI from results of background stuff
});
});
}
So with that in mind, I would suggest something more like this:
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
[self dismissModalViewControllerAnimated:YES];
[self processImage:info];
}
-(void)processImage:(NSDictionary *)info{
animate = true;
UIImage *image = nil;
NSString* mediaType = [info objectForKey:UIImagePickerControllerMediaType];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// processing of image here on background thread
dispatch_async(dispatch_get_main_queue(), ^{
// update UI here on main thread
animate = false;
[activityImageView stopAnimating];
[activityImageView release];
[self.tableView reloadData];
});
});
}
This would offload the main work to a background thread to let the UI stay responsive.
Try to use
[[picker presentingViewController] dismissViewControllerAnimated:YES completion:nil];
instead of:
[[picker parentViewController] dismissModalViewControllerAnimated: YES];

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?
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).
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]];
}
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];
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];
}