UIImagePickerController not showing in iOS 8

Does anyone have problems with UIImagePickerController in iOS 8? The method below works fine in iOS 7 on the iPad, but I get the following error when I run it in Xcode 6 (Beta 3 or 4) when I try to present the collector (last line). If that matters, the choice of sourceType comes from the alertView, which is presented in the same place.

 Warning: Attempt to present <UIImagePickerController: 0x7c0ae400> on <CAGUCreateContactViewController: 0x7bf61a00> which is already presenting (null) 

The way to open imagePicker.

 - (void)openPhotoPicker:(UIImagePickerControllerSourceType)sourceType { if ([UIImagePickerController isSourceTypeAvailable:sourceType]) { NSArray *availableMediaTypes = [UIImagePickerController availableMediaTypesForSourceType:sourceType]; if ([availableMediaTypes containsObject:(NSString *)kUTTypeImage]) { UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init]; imagePickerController.modalPresentationStyle = UIModalPresentationFullScreen; imagePickerController.sourceType = sourceType; imagePickerController.mediaTypes = @[(NSString *)kUTTypeImage]; imagePickerController.delegate = self; self.imagePickerController = imagePickerController; if (sourceType == UIImagePickerControllerSourceTypeCamera) { [self presentViewController:self.imagePickerController animated:YES completion:nil]; } else { if (self.popoverVC) { [self.popoverVC dismissPopoverAnimated:YES]; self.popoverVC = nil; } self.popoverVC = [[UIPopoverController alloc] initWithContentViewController:imagePickerController]; [self.popoverVC presentPopoverFromRect:self.nameAndPicCell.picture.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES]; } } } } 
+55
ios ios8 ipad uiimagepickercontroller
Jul 24 '14 at 19:24
source share
12 answers

I think this is due to the fact that in iOS 8, alert views and action tables are actually represented by view controllers ( UIAlertController ). So, if you present a new view controller in response to an action from a UIAlertView , it is displayed while the UIAlertController rejected. I worked on this, delaying the presentation of the UIImagePickerController until the next runloop iteration, doing the following:

 [[NSOperationQueue mainQueue] addOperationWithBlock:^{ [self openPhotoPicker:sourceType]; }]; 

However, the correct way to fix this is to use the new UIAlertController API for iOS 8 (i.e. use if ([UIAlertController class]) ... to check for it). This is just a workaround if you still cannot use the new API.

+106
Sep 15 '14 at 9:49
source share

I agree with finding a problem with Ben Lings. I would suggest a simpler solution if using a UIActionSheet. I just moved my code that responds to the selection of the Action Sheet:

 - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex; { // my code } 

at

 - (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex; // after animation { // my code } 

Thus, the application ensures that the code is executed. AFTER the completion of the UIActionSheet animation.

Since UIAlertView has a similar delegation method:

 - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex; // after animation { // my code } 

I believe that such a solution can be applied.

+80
Sep 25 '14 at 20:16
source share

Here is the solution that worked for me

 if([[[UIDevice currentDevice] systemVersion] floatValue]>=8.0) { [[NSOperationQueue mainQueue] addOperationWithBlock:^{ [self presentViewController:cameraUI animated:NO completion:nil]; }]; } else{ [controller presentViewController:cameraUI animated:NO completion:nil]; } 

Remember to highlight cameraUI

 UIImagePickerController *cameraUI = [[UIImagePickerController alloc] init]; cameraUI.sourceType = UIImagePickerControllerSourceTypeCamera; 

Build and go!

+12
Sep 16 '14 at 10:07
source share

I encountered the same problem in iOS 8. Then I saw the change log of the latest update for iOS ie 8.0.2 on the device.

This update states that _

"Fixes an issue that prevented some apps from accessing photos from the photo library"

So, test your application using Xcode 6 on a device with iOS 8.0.2, it will work fine. Do not test it on the iOS 8.0 simulator.

It helped me, hopefully the same for you.

Screen-shot of iOS 8.0.2 Update change log

+8
Sep 27 '14 at 12:39 on
source share
 UIImagePickerController *imagePickerController= [[UIImagePickerController alloc] init]; [imagePickerController setSourceType:UIImagePickerControllerSourceTypePhotoLibrary]; // image picker needs a delegate so we can respond to its messages [imagePickerController setDelegate:self]; self.shouldCallViewWillAppear = NO; if(IS_IOS8) { [[NSOperationQueue mainQueue] addOperationWithBlock:^{ // Place image picker on the screen [self presentViewController:imagePickerController animated:YES completion:nil]; }]; } else { [self presentViewController:imagePickerController animated:YES completion:nil]; } 
+4
Sep 22 '14 at 12:47
source share

You can reject the presented view controller (if any) using

 [self.presentedViewController dismissViewControllerAnimated:YES completion:nil]; 

It worked for me.

+3
Jun 29 '16 at 11:22
source share

All you have to do is delete the already submitted ViewController:

 if (self.presentedViewController) { [self.presentedViewController dismissViewControllerAnimated:YES completion:nil]; } [self openPhotoPicker:sourceType]; 

If it still causes an error, put openPhotoPicker: in the completion handler

+2
Oct 13 '14 at 11:46
source share

On iOS 8, you should use the new API:

 if (SYSTEM_VERSION_IOS_8) { self.imagePickerController.modalPresentationStyle = UIModalPresentationPopover; UIPopoverPresentationController *popPC = self.imagePickerController.popoverPresentationController; popPC.barButtonItem = self.popoverItem; popPC.permittedArrowDirections = UIPopoverArrowDirectionAny; [self presentViewController:self.imagePickerController animated:YES completion:nil] } 

I recommend that you watch the 2014 WWDC session 228 look at the side presentation controllers

+1
04 Sep '14 at 4:01
source share

I just did this:

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, (unsigned long)NULL), ^(void) { [self retractActivePopover]; dispatch_async(dispatch_get_main_queue(), ^ { _activePopover=imagePickerPopover; UIBarButtonItem *callingButton = (UIBarButtonItem*) sender; [imagePickerPopover presentPopoverFromBarButtonItem:callingButton permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES]; }); }); 
+1
Sep 24 '14 at 19:28
source share

I went through a lot of pain, coming up with a solution that works on both the iPad and iPhone, this is the final code, which partially comes from other people's comments: the code has some errors, but this is a very good place to run :)

definitions:

 __weak IBOutlet UIButton *attachButton; UIImage *image; 

button action:

  - (IBAction)doAttach:(id)sender { UIActionSheet *action = [[UIActionSheet alloc] initWithTitle:@"Select image from" delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil otherButtonTitles:@"From library",@"From camera", nil] ; [action showInView:self.view]; } #pragma mark - ActionSheet delegates - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex { if( buttonIndex == 1 ) { AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo]; if(authStatus == AVAuthorizationStatusAuthorized) { NSLog(@"%@", @"You have camera access"); } else if(authStatus == AVAuthorizationStatusDenied) { NSLog(@"%@", @"Denied camera access"); [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) { if(granted){ NSLog(@"Granted access to %@", AVMediaTypeVideo); } else { [self.presentedViewController dismissViewControllerAnimated:YES completion:nil]; UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"no camera access" message: @"if you need to use camera in this application go to settings -> appName -> and turn on camera." preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { }]; [alert addAction:defaultAction]; [self presentViewController:alert animated:YES completion:nil]; NSLog(@"Not granted access to %@", AVMediaTypeVideo); return ; } }]; } else if(authStatus == AVAuthorizationStatusRestricted) { [self.presentedViewController dismissViewControllerAnimated:YES completion:nil]; UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"no camera access" message: @"if you need to use camera in this application go to settings -> appName -> and turn on camera." preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { }]; [alert addAction:defaultAction]; [self presentViewController:alert animated:YES completion:nil]; NSLog(@"%@", @"Restricted, normally won't happen"); } else if(authStatus == AVAuthorizationStatusNotDetermined) { NSLog(@"%@", @"Camera access not determined. Ask for permission."); [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) { if(granted){ NSLog(@"Granted access to %@", AVMediaTypeVideo); } else { NSLog(@"Not granted access to %@", AVMediaTypeVideo); return ; } }]; } else { [self.presentedViewController dismissViewControllerAnimated:YES completion:nil]; UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"No camera access" message: @"error accusing camera" preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { }]; [alert addAction:defaultAction]; [self presentViewController:alert animated:YES completion:nil]; return; //NSLog(@"%@", @"Camera access unknown error."); } if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { UIImagePickerController *pickerView =[[UIImagePickerController alloc]init]; pickerView.allowsEditing = YES; pickerView.delegate = self; pickerView.sourceType = UIImagePickerControllerSourceTypeCamera; if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { [ self.presentedViewController dismissViewControllerAnimated:YES completion:nil ]; pickerView.modalPresentationStyle = UIModalPresentationPopover; UIPopoverPresentationController *popPC = pickerView.popoverPresentationController; popPC.sourceView = attachButton; popPC.permittedArrowDirections = UIPopoverArrowDirectionAny; [self presentViewController:pickerView animated:YES completion:nil]; } else { [self presentModalViewController:pickerView animated:YES ]; } } }else if( buttonIndex == 0 ) { ALAuthorizationStatus status = [ALAssetsLibrary authorizationStatus]; switch (status) { case ALAuthorizationStatusRestricted: case ALAuthorizationStatusDenied: { [self.presentedViewController dismissViewControllerAnimated:YES completion:nil]; UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"no access to library" message: @"if you wish to access photos in this app go to settings -> appName-> and turn on photos ." preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction* defaultAction = [UIAlertAction actionWithTitle:@"ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { }]; [alert addAction:defaultAction]; [self presentViewController:alert animated:YES completion:nil]; } break; default: { UIImagePickerController *pickerView = [[UIImagePickerController alloc] init]; pickerView.allowsEditing = YES; pickerView.delegate = self; [pickerView setSourceType:UIImagePickerControllerSourceTypePhotoLibrary]; if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { [ self.presentedViewController dismissViewControllerAnimated:YES completion:nil ]; pickerView.modalPresentationStyle = UIModalPresentationPopover; UIPopoverPresentationController *popup = pickerView.popoverPresentationController; popup.sourceView = attachButton; popup.permittedArrowDirections = UIPopoverArrowDirectionAny; [self presentViewController:pickerView animated:YES completion:nil]; } else { [self presentModalViewController:pickerView animated:YES ]; } } break; } } } #pragma mark - PickerDelegates - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{ [self dismissModalViewControllerAnimated:true]; UIImage * img = [info valueForKey:UIImagePickerControllerEditedImage]; image = img; } 
+1
Apr 09 '16 at 21:05
source share

performSelector: withObject: afterDelay solved my problem.

also did DismissWithButtonIndex do the trick.

Max

0
Jan 18 '15 at 2:35
source share

Here is Khasarin’s decision. For me, I worked on adding my actions to the Dismissed event handler.

 this.btnPhoto.TouchUpInside += (sender, e) => { actionSheet = new UIActionSheet ("Add Photo"); actionSheet.AddButton ("Take Photo"); actionSheet.AddButton ("Select from Library"); actionSheet.AddButton ("Cancel"); actionSheet.DestructiveButtonIndex = -1; // red actionSheet.CancelButtonIndex = 3; // black actionSheet.Clicked += delegate(object a, UIButtonEventArgs b) { actionSheet.Dismissed += (object aSender, UIButtonEventArgs dismissArgs) => { switch (dismissArgs.ButtonIndex) { case 0: showCamera (); break; case 1: showPhotoLibrary (); break; } }; }; actionSheet.ShowInView (view); }; 
0
Feb 06 '16 at 21:45
source share



All Articles