This question already has answers here:
Dismiss UIImagePickerController
(4 answers)
Closed 7 years ago.
Single View controller with single image view:
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
if (self.imageView.image == nil) {
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePickerController.modalPresentationStyle = UIModalPresentationCurrentContext;
imagePickerController.delegate = self;
[self presentViewController:imagePickerController animated:YES completion:nil];
}
else { }
}
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
[picker dismissViewControllerAnimated:YES completion:nil];
[self performSelector:#selector(composeEmail:) withObject:image afterDelay:1.0];
}
- (void) imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[picker dismissViewControllerAnimated:YES completion:nil];
}
What follows is an MFMailComposer but the imagePicker does not dismiss after selecting 'use photo.' The imagePicker seems to dismiss and then reappear.
Here is a link to a Gist For the ViewController:
https://gist.github.com/FIDELHIMSELF/069609eb5489cf4723a1
I get two error warnings:
"Warning: Attempt to present on whose view is not in the window hierarchy!"
and
"Snapshotting a view that has not been rendered results in an empty snapshot. Ensure your view has been rendered at least once before snapshotting or snapshot after screen updates."
try dismissing the view controller like;
[picker dismissViewControllerAnimated:YES completion:nil];
So for example imagePickerControllerDidCancel delegate method would look like;
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
[picker dismissViewControllerAnimated:YES completion:nil];
}
Related
I have a problem where the delegate of UIImagePickerController not being called when presented with sourceType = UIImagePickerControllerSourceTypePhotoLibrary.
Oddly enough, it works perfectly fine in camera mode.
Interface declaration:
#interface ChatVC : UIViewController <UIActionSheetDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate>
And in implementation:
- (void)takePhotoAction {
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
UIImagePickerController* imgPickerController = [[UIImagePickerController alloc] init];
imgPickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
imgPickerController.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
imgPickerController.allowsEditing = YES;
imgPickerController.delegate = self;
[self presentViewController:imgPickerController animated:YES completion:nil];
}
}
- (void)choosePhotoFromLibraryAction {
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
UIImagePickerController* imgPickerController = [[UIImagePickerController alloc] init];
imgPickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imgPickerController.allowsEditing = YES;
imgPickerController.delegate = self;
[self presentViewController:imgPickerController animated:YES completion:nil];
}
}
And here's the delegate method implementation in the same view controller:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary<NSString *,id> *)editingInfo {
NSLog(#"Image Picker Controller Picked Image - Deprecated");
[picker dismissViewControllerAnimated:YES completion:nil];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSLog(#"Image Picker Controller Picked Image");
[picker dismissViewControllerAnimated:YES completion:nil];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
NSLog(#"Image Picker Controller Cancelled");
[picker dismissViewControllerAnimated:YES completion:nil];
}
When opened in camera mode, everything works just fine, and I can see the appropriate delegate methods being called.
But when opened in photo library mode and I choose a photo, nothing happens and no delegate method is called. However, I can see -imagePickerControllerDidCancel: delegate method being called when I tap on Cancel button.
I even suspected memory warning somehow invalidates the delegate, but it was not the case here.
Please someone help me figure this out.
Thanks in advance!
This application loads the device's camera in viewWillAppear method:
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
if (self.imageView.image == nil) {
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePickerController.modalPresentationStyle = UIModalPresentationCurrentContext;
imagePickerController.delegate = self;
[self presentViewController:imagePickerController animated:YES completion:nil];
}
else { }
}
Delegate methods are implemented:
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
[self dismissViewControllerAnimated:YES completion:nil];
// Pass the image to email composer after dismissing the camera. Delay allowed for cameraVC to dismiss.
[self performSelector:#selector(composeEmail) withObject:image afterDelay:1.0];
}
- (void) imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[[picker parentViewController] dismissViewControllerAnimated:YES completion:nil];
}
When a photo is taken and I choose the default "Use Photo" button I want to dismiss the camera ViewController and load the emailComposer View Controller, which uses this method:
- (void) composeEmail: (UIImage *)image {
NSString *bodyHeader = #"Here are you directions:";
NSString *mailBody = [NSString stringWithFormat:#"%#\n%#", bodyHeader, googleMapsURL];
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
[picker setSubject:#"Google Maps Directions"];
[picker setMessageBody:mailBody isHTML:NO];
[picker setToRecipients:#[#"john.doe#gmail.com"]];
[picker setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
// Create NSData object as PNG image data from camera image
NSData *data = UIImagePNGRepresentation(image);
// Attach image data to the email
// 'DestinationImage.png' is file name that will be attached to the email
[picker addAttachmentData:data mimeType:#"image/png" fileName:#"DestinationImage"];
[self presentViewController:picker animated:YES completion:nil];
}
(I have left out some of the MessageUI details here but I have tested it and I know it is working)
The image taken should be passed to the emailComposer and attached as an email. When I build this on my device and tap the "Use Photo" button an error is thrown. The error message states "Attempt to present MFMailCompseViewController on ViewController whose view is not in the window hierarchy!" I am using only one ViewController and that VC contains one Image View.
Can anyone help me dismiss the camera and load the email composer?
Much appreciated!
First Dismiss the ImagePicker and then present ur mailcomposer will work then.U r dismissing the parent thta's y its not working [yourpicker dismissViewControllerAnimated:YES completion:nil];
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
[yourpicker dismissViewControllerAnimated:YES completion:nil];
// Pass the image to email composer after dismissing the camera. Delay allowed for cameraVC to dismiss.
[self performSelector:#selector(composeEmail) withObject:image afterDelay:1.0];
}
To present view controller, use following :
[[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController: picker
animated:YES
completion:nil];
You can also look into this stackoverflow's question for further understanding
I am taking picture from Camera.They Shown me Snapshotting a view that has not been rendered results in an empty snapshot. Ensure your view has been rendered at least once before snapshotting or snapshot after screen updates.
-(IBAction)choosePicture:(id)sender
{
UIImagePickerController *imagePicker=[[UIImagePickerController alloc]init];
imagePicker.sourceType=UIImagePickerControllerSourceTypePhotoLibrary;
imagePicker.delegate=self;
[self presentViewController:imagePicker animated:YES completion:nil];
}
-(IBAction)takePicture:(id)sender
{
UIImagePickerController *imagePicker=[[UIImagePickerController alloc]init];
imagePicker.sourceType=UIImagePickerControllerSourceTypeCamera;
imagePicker.delegate = self;
[self presentViewController:imagePicker animated:YES completion:nil];
}
-(void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info
{
// UIImage *pickedImage=[info objectForKey:UIImagePickerControllerOriginalImage];
image.image = [info objectForKey:#"UIImagePickerControllerOriginalImage"];
picker.modalPresentationStyle = UIModalPresentationFullScreen;
[picker dismissViewControllerAnimated:YES completion:nil];
}
Tried your code in an empty app, had no messages, everything is fine.
Besides downloaded example from apple https://developer.apple.com/library/ios/samplecode/PhotoPicker/Introduction/Intro.html
It has the same problem, but everything works fine. May be it's just a bug. (If their own code has the same message)
If you have this message and something doesn't work correctly, try similar questions. for example: UIImagePickerController error: Snapshotting a view that has not been rendered results in an empty snapshot in iOS 7
This worked for me:
-(IBAction)takePicture:(id)sender
{
UIImagePickerController *imagePickController=[[UIImagePickerController alloc]init];
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
imagePickController.sourceType = UIImagePickerControllerSourceTypeCamera;
}
else
{
imagePickController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
imagePickController.delegate = self;
imagePickController.allowsEditing = TRUE;
[self presentViewController:imagePickController animated:YES completion:nil];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[self dismissViewControllerAnimated:YES completion:nil];
<your image> = [info objectForKey:UIImagePickerControllerEditedImage];
}
After dismiss camera. It give me this warning: Attempt to present on while a presentation is in progress!
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[self dismissViewControllerAnimated:YES completion:nil];
}
I don't know if this is a big issue.
More Code:
- (void) viewWillAppear:(BOOL)animated
{
[self takePicture];
}
- (void) takePicture
{
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
[imagePickerController setSourceType:UIImagePickerControllerSourceTypeCamera];
} else
[imagePickerController setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
imagePickerController.delegate = self;
[self presentViewController:imagePickerController animated:YES completion:nil];
}
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[self dismissViewControllerAnimated:NO completion:nil];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[self dismissViewControllerAnimated:NO completion:nil];
}
By the way, "dismissModalViewController" is deprecated.
Fix:
ViewWillAppear will be invoked once there is a new view. That's the problem
You should not present any controller from viewWillAppear because the presentation of the current view controller is not yet completed.
Call takePicture from viewDidAppear because viewDidAppear will be called once the presentation of controller completed .
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[self takePicture];
}
Hope this will help you.
You probably have presented some view controller like this
[self presentViewController:someVC animated:YES completion:nil];
and before the animation is get completed your below method is called
imagePickerControllerDidCancel
You can check it by changing it to
[self presentViewController:someVC animated:NO completion:nil];
notice animation:NO above.
In my application i have used the following code to implement after dismissing the view i have pushed to new view,When i tried to implement the view is not dismissing instead it overlapping.Here my code,
-(IBAction)selectExitingPicture
{
if([UIImagePickerController isSourceTypeAvailable:
UIImagePickerControllerSourceTypePhotoLibrary])
{
UIImagePickerController *picker= [[UIImagePickerController alloc]init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:picker animated:YES completion:nil];
}
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image
editingInfo:(NSDictionary *)editingInfo
{
[picker dismissViewControllerAnimated:YES completion:^{
cropingImageViewCon = [[CropingImageViewControl alloc]initWithNibName:#"CropingImageView" bundle:nil];
cropingImageViewCon.delegate = self;
cropingImageViewCon.originalImg = image;
[self.navigationController presentModalViewController:cropingImageViewCon animated:YES];
}];
}
Whats wrong with my code,Can any one please help out.
If you want to push into CropingImageViewControl then you are going wrong way,
Use
[self.navigationController pushViewController:yourViewCotrollerObject animated:YES];
instead of using presentModalViewController: