UIImagepicker disappears immediately aftershowing on iPhone - ios

I have 2 Storyboards for iPhone and iPad.
From a Button on a UITableviewcontroller I want to select an Image with a UIImagepicker.
On the iPad this works fine, on the iPhone the UIImagepicker is shown for very short moment and then he disappears.
The calling code is the same for iPad an iPhone and as I can see the storyboards are idenitical. Im looking for hours and cannot see why the Imagepicker disappears on iPhone and on iPad not.
Has anyone an idea for this behaviour? What can be the reason why the UIImagePicker disappears without doing anything?
- (void) go {
UIImagePickerController *ipc = [[UIImagePickerController alloc]init];
[ipc setSourceType:UIImagePickerControllerSourceTypeSavedPhotosAlbum];
ipc.delegate=self;
[self presentViewController:ipc animated:YES completion:^{}];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
NSLog(#"imagePickerControllerDidCancel");
[self dismissViewControllerAnimated:YES completion:^{}];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
[self.navigationController dismissViewControllerAnimated:NO completion:^{}];
[self dismissViewControllerAnimated:NO completion:^{}];
NSLog(#"didFinishPickingMediaWithInfo");
}
On iPhone the log "imagePickerControllerDidCancel" is never shown!

Store the picker in a strong class property instead of a local variable, like this:
#property(nonatomic, strong) UIImagePickerController *imagePickerController
...
- (void) go {
self.imagePickercontroller = [[UIImagePickerController alloc]init];
self.imagePickercontroller.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
self.imagePickercontroller.delegate=self;
[self presentViewController:ipc animated:YES completion:nil];
}

Related

Dismissing the image picker from the didFinishPickingMediaWithInfo method now impossible?

This seems like a simple question and I've seen similar ones answered but the answers just don't work (at least anymore). I have the following code in viewDidAppear:
UIImagePickerController *imagePicker;
imagePicker =[[UIImagePickerController alloc] init];
imagePicker.allowsEditing = YES;
{imagePicker.sourceType=UIImagePickerControllerSourceTypePhotoLibrary;}
imagePicker.delegate=self;
NSLog(#"ViewDidAppear");
[self presentModalViewController:imagePicker animated:YES];
NSLog (#"Modal Window Displayed.");}
This allows the user to select an image from the image library, which works. Once that image is picked, didFinishPickingMediaWithInfo gets called which has this code at the top of it:
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{
NSLog(#"Image Is Picked");
[[picker presentingViewController] dismissViewControllerAnimated:YES completion:nil];
[self dismissModalViewControllerAnimated:YES];
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
[self dismissViewControllerAnimated:NO completion:nil];
[self.navigationController popViewControllerAnimated:YES];
As you can see, I've tried several different ways found here on StackOverflow to get this to work. They all get ignored. No errors, just nothing happens; the picker view never goes away. What gives? I'm using xCode 7.2.1.
I have a similar place in my code where I present another modal view and also can't get rid of it.
The problem is that the didFinishPickingMediaWithInfo method doesn't actually dismiss the other view until it is DONE with it's execution (even if what's running in that method takes almost a minute!). By the time that method was done, I had already presented another viewcontroller modally. Almost all of the techniques I'd been trying all along actually still work.
If you present with presentViewController instead of presentModalViewController:
[self presentViewController:imagePicker animated: YES];
then
[self dismissViewControllerAnimated:YES completion:nil];
should work - perhaps the combination of different functions you are calling all at once is confusing things.
If this doesn't work, perhaps try presenting it with a slight delay with dispatch_after - it could be that presenting it within viewDidAppear is causing the issue:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(0.001 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) {
[self presentViewController:imagePicker animated: YES];
}
Below code works for me perfectly. Hope it helps.
in class.h
#interface class : UIViewController<UIImagePickerControllerDelegate>
{
UIImagePickerController *picker;
}
in class.m when getPhoto called, PickerViewController presented.
- (IBAction)getPhoto:(UIButton *)sender {
picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:picker animated:YES completion:nil];
}
- (void)imagePickerController:(UIImagePickerController *)picker2 didFinishPickingMediaWithInfo:(NSDictionary *)info {
[picker2 dismissViewControllerAnimated:YES completion:nil];
}
Globally declare your imagePicker like below
#implementation ViewController{
UIImagePickerController *imagePicker;
}
Display your image picker declared globally
- (IBAction)chooosePic:(id)sender {
imagePicker =[[UIImagePickerController alloc] init];
imagePicker.allowsEditing = YES; {imagePicker.sourceType=UIImagePickerControllerSourceTypePhotoLibrary;}
imagePicker.delegate=self;
NSLog(#"ViewDidAppear");
[self presentModalViewController:imagePicker animated:YES];
NSLog (#"Modal Window Displayed.");
}
didFinishPickingMediaWithInfo method update as below:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *chosenImage = info[UIImagePickerControllerEditedImage];
self.imageView.image = chosenImage;
[imagePicker dismissViewControllerAnimated:YES completion:NULL];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker dismissViewControllerAnimated:YES completion:NULL];
}
Will Work

UIImagePickerController crashes on cancelling second time

I am using UIImagePickerController in my app and it crashes whenever I click on cancel for 2nd time and shows following crash log :
Terminating app due to uncaught exception
'UIViewControllerHierarchyInconsistency', reason: 'child view
controller: should have parent
view controller:(null) but actual parent is:'
Dismissing code :
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[self dismissViewControllerAnimated:YES completion:nil];
}
The same code is working fine in other app but when I copied the code into new project the crash is occurring repeatedly.
Its happening on iOS 8.3 & 7.1, not tested on other versions.
Any help would be much appreciable.
Set delegate in .h
#interface YourViewController : UIViewController < UIImagePickerControllerDelegate, UINavigationControllerDelegate>
Initialize image picker when you want to open it.
UIImagePickerController *imgPicker = [[UIImagePickerController alloc] init];
imgPicker.delegate = self;
imgPicker.allowsEditing = YES;
imgPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:imgPicker animated:YES completion:^{ }];
Delegate method
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[picker dismissViewControllerAnimated:YES completion:nil];
}

Landscape orientation image picker.

I'm creating an app that is landscape only, it uses an image picker control.
Looking through the site I've discovered that apple only allow portrait for this for some reason. I'm okay with it flipping to portrait for this one section, if it means the user can select a photo from the library.
Below is my code that gives an error about it being in landscape mode. How do I fix this to say it's okay to flip it to portrait. thanks
-(IBAction)takePhoto{
takePicker = [[UIImagePickerController alloc]init];
takePicker.delegate = self;
[takePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
[self presentViewController:takePicker animated:YES completion:NULL];
}
-(IBAction)chooseExisiting{
choosePicker = [[UIImagePickerController alloc]init];
choosePicker.delegate = self;
[choosePicker setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
[self presentViewController:choosePicker animated:YES completion:NULL];
}
You don't have to use ImagePickerController in portrait mode.
Just subclass it to open in landscape mode :
#interface NonRotatingUIImagePickerController : UIImagePickerController
#end
#implementation NonRotatingUIImagePickerController
- (BOOL)shouldAutorotate
{
return NO;
}
#end
After that, you can use your code with that class.
-(IBAction)takePhoto {
takePicker = [[NonRotatingUIImagePickerController alloc]init];
takePicker.delegate = self;
[takePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
[self presentViewController:takePicker animated:YES completion:NULL];
}
-(IBAction)chooseExisiting{
choosePicker = [[NonRotatingUIImagePickerController alloc]init];
choosePicker.delegate = self;
[choosePicker setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
[self presentViewController:choosePicker animated:YES completion:NULL];
}
Why present an error at all? Why not just present the image picker in portrait? People are smart enough to rotate their device. Or you could write your own landscape image picker, or use one of the several open source ones available.

Understanding how to dismiss a UIImagePickerController

I'm a bit confused, this isn't a question on how to dismiss a UIImagePickerController, it's more of a "why did that work" type of question. I am working in iOS7.
Looking online at the apple documentation (this link: https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/CameraAndPhotoLib_TopicsForIOS/Articles/TakingPicturesAndMovies.html#//apple_ref/doc/uid/TP40010406-SW6), I came across the following code for dismissing a UIImagePickerController:
[[picker parentViewController] dismissModalViewControllerAnimated: YES];
Edit: I know that that method was deprecated, so instead I tried the following, and that did not work either:
[[picker parentViewController] dismissViewControllerAnimated:YES completion:NULL];
Those didn't work for me. This however did work:
[picker dismissViewControllerAnimated:YES completion:NULL];
Is the apple documentation wrong? or just outdated?
Why does the second bit of code work, because from my understanding, its the parent view controllers job to dismiss something like a popover or in this case a UIImagePickerController
Thank you.
Edit: This is how I am presenting the UIImagePickerController, the UITapGestureRecognizer calls the first method which then calls the second.
- (IBAction)captureMoment:(UITapGestureRecognizer *)sender {
[self startCameraCaptureFromViewController:self usingDelegate:self];
}
- (BOOL)startCameraCaptureFromViewController:(UIViewController *)controller
usingDelegate:(id <UIImagePickerControllerDelegate, UINavigationControllerDelegate>)delegate {
if (delegate == nil || controller == nil || [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] == NO) {
return NO;
}
UIImagePickerController *camera = [[UIImagePickerController alloc] init];
camera.sourceType = UIImagePickerControllerSourceTypeCamera;
camera.allowsEditing = NO;
camera.delegate = delegate;
[controller presentViewController:camera animated:YES completion:NULL];
return YES;
}
There are 2 methods that worked for me
Use picker.presentingViewController instead of picker.parentViewController, answer by rmaddy
Use the following code in the imagePickerControllerDidCancel:, [picker dismissViewControllerAnimated:YES completion:NULL];
Here is the code in its entirety, this is placed in the UIViewController that presents the UIImagePickerController:
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker.presentingViewController dismissViewControllerAnimated:YES completion:NULL];
}
The method dismissModalViewControllerAnimated has been deprecated since iOS6. The new method you are using is the correct one.

Removing UIImagePickerController from UINavigationController in a UIPopoverController

This worked in iOS6, so not sure what the issue is.
inside my UINavigationController (ioNavController) I present the UIImagePickerController with the Following:
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.modalInPopover = YES;
imagePicker.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:imagePicker animated:NO completion:^{ }];
in my UIImagePickerControllerDelegate (which does get called)I have the Following:
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
//This does not work
[ioNavController dismissViewControllerAnimated:YES completion:^{ /* Cleanup if Needed */ }];
//This does not work
[[picker parentViewController] dismissViewControllerAnimated:YES completion:^{ /* Cleanup if Needed */ }];
//This does not work
[picker removeFromParentViewController];
// This presents a new view on the Nav Controller. It shows the new view ontop of the ImagePicker. Image Picker View does not repond to touches.
[ioNavController pageToSelect:0];
}
Your delegate it's in the same controller that called the imagepicker? The same controller that called presentViewController should call the line below, and the imagepicker will be removed correctly.
[self dismissViewControllerAnimated:YES completion:nil]; //self here it's the same reference that called presentViewController
let me know if worked or helped.
The UIImagePickerController will remove itself when you use this code:
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)pPicker {
[pPicker dismissViewControllerAnimated:YES completition:NULL]; }

Resources