UIImagePickerController nie prezentuje się w iOS 8

Czy ktoś jeszcze ma problem z UIImagePickerController w iOS 8? Poniższa metoda działa doskonale w iOS 7 na iPadzie, ale dostaję następujący błąd, gdy uruchamiam to w XCode 6 (Beta 3 lub 4), gdy próbuję przedstawić picker (ostatnia linia). Jeśli ma to znaczenie, wybór typu źródła pochodzi z widoku alertView, który jest prezentowany w tym samym miejscu.

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

Metoda otwierania imagepickera.

- (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];
            }
        }
    }
}
Author: Eugen Martynov, 2014-07-24

12 answers

Myślę, że to dlatego, że w iOS 8 widoki alertów i arkusze akcji są rzeczywiście prezentowane Kontrolery widoku (UIAlertController). Tak więc, jeśli prezentujesz nowy kontroler widoku w odpowiedzi na działanie z UIAlertView, jest on prezentowany podczas gdy UIAlertController jest odrzucany. W ten sposób udało mi się opóźnić prezentację UIImagePickerController do następnej iteracji runloopa, wykonując to:

[[NSOperationQueue mainQueue] addOperationWithBlock:^{
    [self openPhotoPicker:sourceType];
}];
Aby to naprawić, należy użyć nowego API UIAlertController w systemie iOS 8 (np. użyć if ([UIAlertController class]))... na test na to). Jest to tylko obejście, jeśli nie możesz jeszcze korzystać z nowego API.
 108
Author: Ben Lings,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-18 10:59:34

Zgadzam się z Benem Lingsem. Proponowałbym prostsze rozwiązanie w przypadku korzystania z UIActionSheet. Po prostu przeniosłem mój kod, który reaguje na wybór arkusza akcji z:

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

Do:

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

W ten sposób aplikacja ma gwarancję, że kod zostanie wykonany po zakończeniu animacji interfejsu użytkownika.

Ponieważ UIAlertView ma podobną metodę delegata:

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

Przypuszczam, że podobne rozwiązanie może mieć zastosowanie.

 80
Author: vedrano,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-25 20:16:04

Oto rozwiązanie, które zadziałało dla mnie

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];
}

Pamiętaj o alloc cameraUI

UIImagePickerController *cameraUI = [[UIImagePickerController alloc] init];
cameraUI.sourceType = UIImagePickerControllerSourceTypeCamera;
Buduj i ruszaj!
 12
Author: Tunvir Rahman Tusher,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-13 08:44:36

Miałem ten sam problem w iOS 8. Następnie zobaczyłem dziennik zmian najnowszej aktualizacji do iOS tj.

W tej aktualizacji jest wspomniane, że_

"Naprawiono problem, który uniemożliwiał niektórym aplikacjom dostęp do zdjęć z biblioteki zdjęć"

Więc przetestuj swoją aplikację za pomocą XCode 6 na urządzeniu z wersją iOS 8.0.2 będzie działać dobrze Nie testuj go na symulatorze iOS 8.0.

To mi pomogło, mam nadzieję, że to samo dla Ciebie.

Zrzut ekranu dziennika zmian aktualizacji iOS 8.0.2

 8
Author: Piyush Mathur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-27 12:39:25
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
Author: Nirav Gadhiya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-09 05:56:40

Możesz odrzucić prezentowany kontroler widoku (jeśli istnieje) za pomocą

[self.presentedViewController dismissViewControllerAnimated:YES completion:nil];
To mi pomogło.
 3
Author: Ritu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-29 12:12:45

Wszystko, co musisz zrobić, to odrzucić już zaprezentowany ViewController:

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

[self openPhotoPicker:sourceType];

Jeśli nadal generuje błąd, umieść openphotopicker: do obsługi zakończenia

 2
Author: Nikolay Krasnov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-13 11:46:27

Po prostu to zrobiłem:

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
Author: Sebastian Dwornik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-24 19:28:43

Na iOS 8 powinieneś użyć nowego 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]
}

Polecam obejrzeć 2014 WWDC session 228 a look in side presentation controllers

 1
Author: Vito Ziv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-25 02:24:17

Przeszedłem przez wiele bólu wymyślając rozwiązanie, które działa zarówno na iPadzie, jak i iPhonie, jest to ostateczny kod, który część z nich pochodzi z komentarzy innych ludzi: kod ma kilka błędów, ale to bardzo dobre miejsce, aby zacząć:)

Definicje:

__weak IBOutlet UIButton *attachButton;
UIImage *image;

Działanie przycisku:

    - (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
Author: Omid S.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-09 21:05:44

PerformSelector: withObject: afterDelay rozwiązał mój problem.

Również didismisswithbuttonindex zrobić trick.

Max

 0
Author: masgar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-18 02:35:29

Oto roztwór Xamarinu. To, co działało dla mnie, to dodanie moich działań do zwolnionego opiekuna wydarzeń.

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
Author: Vincent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-06 21:45:43