Erreur UIImagePickerController: l'instantané d'une vue qui n'a pas été rendue entraîne un instantané vide dans iOS 7

103

Je reçois cette erreur uniquement dans iOS 7 et l'application s'est plantée. Dans iOS 6, je n'obtiens jamais d'erreur, juste une fois d'avertissement de mémoire lors de l'ouverture de la caméra.

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.

Voici ce que je fais.

imagePicker = [[UIImagePickerController alloc] init];
[imagePicker setDelegate:self];
[imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
[imagePicker setAllowsEditing:YES];

[self presentModalViewController:imagePicker animated:YES];

J'ai essayé de retarder le presentModalViewController, mais je reçois toujours le même message. Après quelques secondes (7-10), l'application s'est plantée.

Cette erreur n'est présente que dans iOS 7.

Quelqu'un a-t-il la moindre idée?

Didats Triadi
la source
3
J'ai le même problème. Sur iOS7, UIIMagePickerController ne fonctionne plus.
condor304
L'appel de cette méthode a fonctionné pour moi. Placez-le après avoir présenté votre vue. [yourViewBeingPresented.view layoutIfNeeded];
Bobby

Réponses:

32

Le problème dans iOS7 est lié aux transitions. Il semble que si une transition précédente ne s'est pas terminée et que vous en lancez une nouvelle, iOS7 gâche les vues, où iOS6 semble la gérer correctement.

Vous devez initialiser votre caméra dans votre UIViewController, uniquement après le chargement de la vue et avec un délai d'expiration:

- (void)viewDidAppear:(BOOL)animated 
{
    [super viewDidAppear:animated];
    //show camera...
    if (!hasLoadedCamera)
        [self performSelector:@selector(showcamera) withObject:nil afterDelay:0.3];
}

et voici le code d'initialisation

- (void)showcamera {
    imagePicker = [[UIImagePickerController alloc] init];
    [imagePicker setDelegate:self];
    [imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
    [imagePicker setAllowsEditing:YES];

    [self presentModalViewController:imagePicker animated:YES];
}
Lefteris
la source
1
Cela semble fonctionner jusqu'à présent, je l'ai testé en prenant 10 photos les unes après les autres sans problème.
DevC
3
presentModalViewController est obsolète dans iOS 6. Il est suggéré d'utiliser presentViewController maintenant.
Gallymon
5
Le même problème et le même correctif pour iOS8.
Yauheni Shauchenka
1
J'essaie de faire fonctionner cela à partir d'un UIAertControl - une option est de présenter le sélecteur d'images pour le navigateur de photos - cela fonctionne bien et l'autre est de présenter pour l'appareil photo - ce n'est pas le cas. un UIALertController?
SimonTheDiver
3
Je n'initialise pas la caméra dans viewDidAppear / Load. J'ai une vue de table, et j'appelle la caméra en réponse à l'un des choix de vue de table. Et je reçois ce message d'erreur. Des idées?
Henning
18

Cette erreur s'est également manifestée pour moi avec le projet de code d'exemple PhotoPicker d'Apple.

J'utilisais Xcode Version 5.0 et iOS 7.0.3 sur un iPhone 4.

Étapes à suivre pour reproduire:

  1. Téléchargez l'exemple de projet PhotoPicker d'Apple à l' adresse https://developer.apple.com/library/ios/samplecode/PhotoPicker/Introduction/Intro.html

  2. Dans APLViewController.m commentez la ligne 125

    //imagePickerController.showsCameraControls = NO;

  3. Dans APLViewController.m commentez les lignes 130-133

    //[[NSBundle mainBundle] loadNibNamed:@"OverlayView" owner:self options:nil];
    // self.overlayView.frame = imagePickerController.cameraOverlayView.frame;
    // imagePickerController.cameraOverlayView = self.overlayView;
    // self.overlayView = nil;

  4. Créez et lancez l'application.

  5. Une fois lancé, faites pivoter l'appareil en mode Paysage.

  6. Cliquez sur l'icône Appareil photo pour ouvrir UIImagePickerController en mode Appareil photo.

  7. Affichez la sortie de la console.

Sortie de la console

PhotoPicker [240: 60b] Instantané d'une vue qui n'a pas été rendue entraîne un instantané vide. Assurez-vous que votre vue a été rendue au moins une fois avant la capture ou la capture après les mises à jour de l'écran.

showsCameraControls, propriété

Le problème se produit pour moi lorsque cela a une valeur de OUI (la valeur par défaut).

Le réglage sur NON a éliminé le message.

Rapport d'erreur

Je viens de déposer un rapport de bogue avec Apple.

J'ai essayé de nombreuses suggestions qui ont été faites dans différents articles, mais je n'ai pas trouvé de solution de contournement satisfaisante.

Scott Carter
la source
1
Comment Apple vous a répondu? J'ai le même problème et les solutions dans stackoverflow ne fonctionnent pas.
heekyu
Je n'ai pas encore entendu d'Apple à ce sujet. Je posterai une réponse si j'obtiens une réponse de leur part.
Scott Carter
Des nouvelles d'Apple? @ScottCarter
Benjamin Toueg
1
Je viens de vérifier à nouveau. Aucune action sur le bogue ouvert depuis son dépôt le 2 novembre 2013.
Scott Carter
Il s'agit du bogue 15377241 sur bugreport.apple.com
Scott Carter
11

J'ai eu le problème lorsque j'ai essayé de présenter la vue de la caméra à l'intérieur d'un popover. Sous iOS6, ce n'était pas un problème mais dans iOS7 j'ai reçu le message

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.

ainsi que.

Cependant, après avoir changé la présentation de la vue de la caméra en plein écran, comme décrit dans Prendre des photos et des films, iOS Developer Library, tout s'est bien passé et le message n'est plus jamais réapparu. Cependant, je devais m'assurer que, selon le mode dans lequel se trouve l'application (c'est-à-dire, présenter la vue de la caméra ou la pellicule photo), je devais soit rejeter le popover soit le contrôleur de vue chaque fois que la méthode - (void) imagePickerControllerDidCancel: (UIImagePickerController *) pickerétait appelée.

Arne
la source
3
cameraUI.modalPresentationStyle = UIModalPresentationFullScreen; travaille pour moi. C'est la seule chose qui a réussi ici. Merci!
daveMac
2
Finalement! J'ai eu ce problème à plusieurs reprises et je n'ai jamais trouvé de bonne solution. Sentez-vous si stupide maintenant de ne jamais regarder plus bas dans les fils de questions - imagePicker.modalPresentationStyle = UIModalPresentationFullScreen; résolu cela pour moi. Cela devrait être la réponse acceptée :)
woobione
6

créer une propriété

@property (nonatomic) UIImagePickerController *imagePickerController;

ensuite

UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.modalPresentationStyle = UIModalPresentationCurrentContext;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
picker.allowsEditing = YES;
self.imagePickerController = picker;
[self presentViewController:self.imagePickerController animated:YES completion:nil];

Cela devrait résoudre le problème

Asfanur
la source
3
picker.modalPresentationStyle = UIModalPresentationCurrentContext; fait la différence pour moi.
M. Berna
1
Cela fonctionne la première fois que le sélecteur est présenté, mais après cela, l'avertissement revient.
daveMac
Je confirme picker.modalPresentationStyle = UIModalPresentationCurrentContext; Résout pour moi le problème des mauvaises mises en page dans iOS 8
João Nunes
Ne fonctionne pas pour moi - ajouté ceci à une action UIButton sur iOS 8.1.3
Andy
Cela semblait prometteur, mais n'a rien fait pour moi pour le problème de la capture instantanée ET a affiché un cadre inutile autour d'une partie de l'image après la prise d'une photo.
dessiné ..
4

J'ai utilisé ce code pour contourner le problème:

UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
[imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
[imagePicker setDelegate:self];

if ([self respondsToSelector:@selector(presentViewController:animated:completion:)]){
    [imagePicker setShowsCameraControls:NO];
    [self presentViewController:imagePicker animated:YES completion:^{
        [imagePicker setShowsCameraControls:YES];
    }];
} else {
    [imagePicker setShowsCameraControls:YES];
    [self presentModalViewController:imagePicker animated:YES];
}
Germán Marquès
la source
1
Bien que l'idée fonctionne en théorie, malheureusement, les commandes affichées ne fonctionnent pas ou n'apparaissent pas correctement.
daveMac
Et cela n'a pas éliminé l'avertissement non plus (pour moi du moins)
Ege Akpinar
3

J'ai le même problème et j'ai trouvé une solution. Je pense que cette erreur est liée à l'orientation de votre application. Mon application utilise uniquement le mode paysage, mais UIImagePickerController utilise le mode portrait. J'ajoute un bloc try-catch à main.m et j'obtiens une vraie exception:

Supported orientations has no common orientation with the application, and shouldAutorotate is returning YES

Comment résoudre ce problème:

1) Vérifiez à nouveau l'orientation de l'appareil dans le fichier Cible-> Général ou .plist: Orientations d'interface prises en charge: Paysage à gauche, Paysage à droite.

2) Ajouter dans AppDelegate.m:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
    return UIInterfaceOrientationMaskLandscape | UIInterfaceOrientationMaskPortrait;
}

Après cette étape, UIImagePickerController fonctionne correctement, mais mes viewcontrollers peuvent être tournés en mode portrait. Donc, pour résoudre ceci:

3) Créez une catégorie pour UINavigationController, (supportedInterfaceOrientations déplacé de UIViewController vers UINavigationController dans iOS6):

@implementation UINavigationController (RotationIOS6)

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
}

@end

Cette solution fonctionne correctement sur iOS 6.0, 6.1, 7.0. J'espère que cela t'aides.

Roman Ermolov
la source
1
Je corrige une application en mode portrait qui donne l'erreur mentionnée dans OP. Il semblerait donc que votre solution ne soit pas universellement applicable.
JohnK
Avez-vous essayé d'ajouter un bloc try-catch à main.m et imprimer l'exception et stacktrace?
Roman Ermolov
Comme ça ?
JohnK du
@JohnK ouais, comme ça.
Roman Ermolov
3

J'obtiens cette erreur lors de la création d'une application avec le SDK iOS 6.1, la cible de déploiement iOS 6.1 et l'exécution de l'application sur un iPhone alimenté par iOS 7. L'application ne plante pas, mais la UIViewController shouldAutorotateméthode de mise en œuvre m'aide à supprimer le message d'erreur.

- (BOOL)shouldAutorotate {
    return YES;
}
Grigori A.
la source
3

J'ai eu le même problème lorsque j'essayais de modifier l'application de démonstration fournie avec le SDK Avirary , dans l'application de démonstration, elle ne peut modifier que la photo sélectionnée dans la pellicule. Pour essayer de modifier la photo en capturant à partir de la caméra, j'ai d'abord ajouté le code suivant dans le fichier UIViewcontroller.m:

#pragma mark - Take Picture from Camera
- (void)showCamera
{
//[self launchPhotoEditorWithImage:sampleImage highResolutionImage:nil];

    if ([self hasValidAPIKey]) {
        UIImagePickerController * imagePicker = [UIImagePickerController new];
        [imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
        [imagePicker setDelegate:self];
        [imagePicker setAllowsEditing:YES]; //important, must have

        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
            [self presentViewController:imagePicker animated:YES completion:nil];
        }else{
            [self presentViewControllerInPopover:imagePicker];
        }
    }
}

Ensuite, lorsque j'exécute l'application, l'erreur s'est produite:

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.

Pour résoudre l'erreur, modifiez le délégué UIImagePicker dans votre fichier UIViewContooler.m comme indiqué ci-dessous:

#pragma mark - UIImagePicker Delegate

- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    NSURL * assetURL = [info objectForKey:UIImagePickerControllerReferenceURL];

    void(^completion)(void)  = ^(void){

        [[self assetLibrary] assetForURL:assetURL resultBlock:^(ALAsset *asset) {
            if (asset){
                [self launchEditorWithAsset:asset];
            }
        } failureBlock:^(NSError *error) {
            [[[UIAlertView alloc] initWithTitle:@"Error" message:@"Please enable access to your device's photos." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
        }];

        UIImage * editedImage = [info objectForKey:UIImagePickerControllerEditedImage];
        if(editedImage){
            [self launchPhotoEditorWithImage:editedImage highResolutionImage:editedImage];
        }

    };

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
        [self dismissViewControllerAnimated:YES completion:completion];
    }else{
        [self dismissPopoverWithCompletion:completion];
    }

}    

Ensuite, l'erreur a disparu et l'application fonctionne!

Tony
la source
1

Essayez ceci, utilisez

[self performSelector:@selector(presentCameraView) withObject:nil afterDelay:1.0f];

et fonction

-(void)presentCameraView{
    [self presentViewController:imagePicker animated:YES completion:nil];
}

remplacer. [self presentModalViewController:imagePicker animated:YES]; et de cause make imagePickercomme variable globale.

JerryZhou
la source
1

C'est ce qui a résolu le problème pour moi sur mon application, ymmv

tout d'abord, c'est une application iPhone - iPad

dans appname-Info.plist. dans les orientations d'interface prises en charge (iPad) a montré 4 orientations.

dans les orientations d'interface prises en charge ont montré 3 orientations. J'ai ajouté le quatrième et j'ai exécuté l'application, pas de sortie de débogage.

J'espère que cela t'aides.

user1045302
la source
0

Je viens de rencontrer le même problème. Dans mon cas, le problème était que j'avais du code non-ARC et que je l'ai migré vers ARC. Lorsque j'ai effectué la migration, je n'avais pas de référence forte à la UIImagePickerControlleret c'était la raison du crash.

J'espère que ça aide :)

arturgrigor
la source
0

J'ai eu le même problème dans iOS 8, mais l'accès à la caméra était désactivé dans Paramètres -> Confidentialité pour mon application. Je l'ai juste activé, et cela fonctionnait.

BhushanVU
la source
0

J'ai passé beaucoup de temps à essayer de trouver la solution, et étonnamment je l'ai trouvée à la fin et c'était juste très drôle une fois que je l'ai découverte.

Voici ce que vous allez faire pour récupérer l'image que vous avez choisie et reprendre le travail :)

-(void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info
{
    UIImage* pickedImage = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
    [composeImageView setImage:pickedImage];
[picker dismissViewControllerAnimated:YES completion:nil];
 }

Oui, pour résoudre le problème, il vous suffit de fermer le sélecteur normalement car il semble que ce message: "Prendre un instantané d'une vue qui n'a pas été rendue entraîne un instantané vide. Assurez-vous que votre vue a été rendue au moins une fois avant la capture ou la capture après mises à jour d'écran. " empêche le sélecteur d'être réactif, mais vous pouvez le rejeter et récupérer l'image normalement.

DevSherif
la source
0

Dans mon cas, c'était lié à un changement de mise en page: le VC présentant le UIImagePickerViewControllera la barre d'état cachée, mais UIImagePickerViewControllerpas.

Donc, je l'ai résolu en cachant la barre d'état dans le UIImagePickerViewControllercomme indiqué dans cette réponse .

Kanobius
la source
-1

Vous ne répondez pas directement à votre question, mais vous avez mentionné que vous aviez un avertissement de mémoire, vous stockez peut-être l'image brute dans une propriété, ce qui peut entraîner un avertissement de mémoire. Cela est dû au fait que l'image brute occupe environ 30 Mo de mémoire. J'ai remarqué un avertissement de mémoire similaire lors du test d'applications sur iOS6 qui étaient sur la série iPhone 4. J'ai toujours reçu cet avertissement lorsque les appareils ont été mis à niveau vers iOS7. Il n'y a pas d'avertissement de mémoire lors des tests sur la série iPhone 5 sur iOS7.

DevC
la source
-5

En changeant

[self presentViewController:imagePicker animated:YES completion:nil];

à

[self presentViewController:imagePicker animated:YES completion:NULL];

a corrigé le problème pour moi.

Yuki
la source