Erro UIImagePickerController: o instantâneo de uma visualização que não foi renderizada resulta em um instantâneo vazio no iOS 7

103

Estou recebendo este erro apenas no iOS 7 e o aplicativo travou. No iOS 6, nunca recebo nenhum erro, apenas uma vez de aviso de memória ao abrir a câmera.

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.

Aqui está o que estou fazendo.

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

[self presentModalViewController:imagePicker animated:YES];

Tentei atrasar o presentModalViewController, mas continuo recebendo a mesma mensagem. Após alguns segundos (7-10), o aplicativo travou.

Este erro está presente apenas no iOS 7.

Alguém tem a pista?

Didats Triadi
fonte
3
Eu tenho o mesmo problema. No iOS7, o UIIMagePickerController não está mais funcionando.
condor304 de
Chamar esse método funcionou para mim. Posicione-o depois de apresentar sua visão. [yourViewBeingPresented.view layoutIfNeeded];
Bobby

Respostas:

32

O problema no iOS7 tem a ver com transições. Parece que se uma transição anterior não foi concluída e você lançou uma nova, o iOS7 bagunça as visualizações, onde o iOS6 parece gerenciá-la corretamente.

Você deve inicializar sua câmera no seu UIViewController, somente depois que a visualização for carregada e com um tempo limite:

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

e aqui está o código de inicialização

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

    [self presentModalViewController:imagePicker animated:YES];
}
Lefteris
fonte
1
Isso parece funcionar até agora, eu testei tirando 10 fotos uma após a outra sem nenhum problema.
DevC
3
presentModalViewController tornou-se obsoleto no iOS 6. É sugerido que presentViewController seja usado agora.
Gallymon
5
O mesmo problema e correção para iOS8.
Yauheni Shauchenka
1
Estou tentando fazer isso funcionar a partir de um UIAertControl - uma opção é apresentar o seletor de imagens para o navegador de fotos - isso funciona bem e a outra é apresentar para a câmera - isso não funciona. um UIALertController?
SimonTheDiver
3
Não inicializo a câmera em viewDidAppear / Load. Eu tenho um tableview e abro a câmera em resposta a uma das opções do tableview. E recebo esta mensagem de erro. Alguma ideia?
Henning
18

Este erro também apareceu para mim com o projeto de exemplo de código PhotoPicker da Apple.

Eu estava usando o Xcode versão 5.0 e iOS 7.0.3 em um iPhone 4.

Passos para reproduzir:

  1. Baixe o projeto de amostra PhotoPicker da Apple em https://developer.apple.com/library/ios/samplecode/PhotoPicker/Introduction/Intro.html

  2. Em APLViewController.m, comente a linha 125

    //imagePickerController.showsCameraControls = NO;

  3. Em APLViewController.m, comente as linhas 130-133

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

  4. Crie e inicie o aplicativo.

  5. Depois de lançado, gire o dispositivo para o modo Paisagem.

  6. Clique no ícone da câmera para abrir o UIImagePickerController no modo Câmera.

  7. Veja a saída do console.

Saída do console

PhotoPicker [240: 60b] Tirar um instantâneo de uma vista que não foi renderizada resulta em um instantâneo vazio. Certifique-se de que sua visualização tenha sido renderizada pelo menos uma vez antes da captura instantânea ou captura instantânea após as atualizações da tela.

propriedade showsCameraControls

O problema ocorre para mim quando este tem um valor SIM (o padrão).

Definir como NÃO eliminou a mensagem.

Relatório de erro

Acabei de preencher um relatório de bug com a Apple.

Tentei muitas das sugestões que foram feitas em diferentes postagens, mas não encontrei uma solução alternativa satisfatória.

Scott Carter
fonte
1
Como a apple respondeu a você? Eu tenho o mesmo problema e soluções em stackoverflow não funcionam.
heekyu 01 de
Ainda não ouvi da Apple sobre isso. Postarei uma resposta se obtiver uma resposta deles.
Scott Carter,
Alguma notícia da Apple? @ScottCarter
Benjamin Toueg
1
Apenas verifiquei novamente. Nenhuma ação sobre o bug aberto desde que foi arquivado em 2 de novembro de 2013.
Scott Carter
Este é o bug 15377241 em bugreport.apple.com
Scott Carter,
11

Tive o problema quando tentei apresentar a visão da câmera dentro de um popover. No iOS6 isso não foi problema, mas no iOS7 recebi a mensagem

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.

também.

No entanto, depois de alterar a apresentação da visualização da câmera para tela inteira, conforme descrito em Tirar fotos e filmes, Biblioteca de desenvolvedores iOS, tudo correu bem novamente e a mensagem nunca mais apareceu. No entanto, tive que me certificar de que dependendo do modo em que o aplicativo está (ou seja, apresentando a visualização da câmera ou o rolo de fotos), teria que dispensar o popover ou o controlador de visualização sempre que o método - (void) imagePickerControllerDidCancel: (UIImagePickerController *) pickerfosse chamado.

Arne
fonte
3
cameraUI.modalPresentationStyle = UIModalPresentationFullScreen; funciona para mim. É a única coisa que deu certo aqui. Obrigado!
daveMac
2
Finalmente! Já tive esse problema muitas vezes e nunca encontrei uma boa solução. Sinta-se tão estúpido agora por nunca olhar mais para baixo nos tópicos de perguntas - imagePicker.modalPresentationStyle = UIModalPresentationFullScreen; resolveu isso para mim. Esta deve ser a resposta aceita :)
woobione
6

criar uma propriedade

@property (nonatomic) UIImagePickerController *imagePickerController;

Então

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

Isso deve resolver o problema

Asfanur
fonte
3
picker.modalPresentationStyle = UIModalPresentationCurrentContext; fez a diferença para mim.
Sr. Berna
1
Funciona na primeira vez que o selecionador é apresentado, mas depois disso o aviso retorna.
daveMac
eu confirmo picker.modalPresentationStyle = UIModalPresentationCurrentContext; Resolve para mim o problema de layouts errados no iOS 8
João Nunes
Não está funcionando para mim - adicionado a uma ação UIButton no iOS 8.1.3
Andy
Isso parecia promissor, mas não ajudou em nada a questão do instantâneo E exibiu um quadro inútil ao redor de uma parte da imagem depois que uma foto foi tirada.
empatou ..
4

Usei este código para solucionar o problema:

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
fonte
1
Embora a ideia funcione em teoria, infelizmente os controles mostrados não funcionam ou aparecem corretamente.
daveMac
E também não
eliminou
3

Eu tenho o mesmo problema e encontrei uma solução. Acho que esse erro relacionado com a orientação do seu aplicativo. Meu aplicativo usa apenas o modo paisagem, mas UIImagePickerController usa o modo retrato. Eu adiciono o bloco try-catch ao main.m e obtenho uma exceção real:

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

Como eu resolvo esse problema:

1) Verifique novamente a orientação do dispositivo em Alvo-> Geral ou arquivo .plist: Orientações de interface suportadas: Paisagem à esquerda, Paisagem à direita.

2) Adicionar AppDelegate.m:

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

Após esta etapa, UIImagePickerController funciona corretamente, mas meus viewcontrollers podem ser girados para o modo retrato. Então, para resolver isso:

3) Crie uma categoria para UINavigationController, (supportedInterfaceOrientations movido de UIViewController para UINavigationController no iOS6):

@implementation UINavigationController (RotationIOS6)

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
}

@end

Esta solução funciona corretamente no iOS 6.0, 6.1, 7.0. Espero que isto ajude.

Roman Ermolov
fonte
1
Estou consertando um aplicativo no modo retrato que apresenta o erro mencionado no OP. Portanto, parece que sua solução não é universalmente aplicável.
JohnK
Você tentou adicionar o bloco try-catch ao main.m e imprimir exceção e rastreamento de pilha?
Roman Ermolov
Gosta disso ?
JohnK
@JohnK sim, assim.
Roman Ermolov
3

Recebo este erro ao construir um aplicativo com iOS SDK 6.1, implantação de destino iOS 6.1 e execução de aplicativo no iOS 7 com iPhone. O aplicativo não trava, mas a implementação do UIViewController shouldAutorotatemétodo me ajuda a remover a mensagem de erro.

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

Eu tive o mesmo problema quando estava tentando modificar o aplicativo demo que vem com o Avirary SDK , no aplicativo demo, ele só pode editar a foto tirada do rolo da câmera. Para tentar editar a foto capturando da câmera, primeiro adicionei o seguinte código no arquivo 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];
        }
    }
}

Então, ao executar o aplicativo, ocorreu o erro:

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.

Para resolver o erro, modifique o delegado UIImagePicker em seu arquivo UIViewContooler.m conforme mostrado abaixo:

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

}    

Então o erro desapareceu e o app funciona!

Tony
fonte
1

Tente isso, use

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

e função

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

para substituir. [self presentModalViewController:imagePicker animated:YES]; e de causa marca imagePickercomo uma variável global.

JerryZhou
fonte
1

Isso é o que corrigiu para mim no meu aplicativo, ymmv

primeiro é um aplicativo para iPhone - iPad

em appname-Info.plist. nas orientações de interface suportadas (iPad) mostrou 4 orientações.

nas orientações da interface suportada mostrou 3 orientações. Eu adicionei o quarto e executei o aplicativo, sem saída de depuração.

Espero que isto ajude.

user1045302
fonte
0

Acabei de encontrar o mesmo problema. No meu caso, o problema era que eu tinha algum código não ARC e migrei para o ARC. Quando fiz a migração, não tinha uma referência forte aoUIImagePickerController e esse foi o motivo do travamento.

Espero que ajude :)

Arturgrigor
fonte
0

Eu tive o mesmo problema no iOS 8, mas o acesso à câmera estava desabilitado em Configurações -> Privacidade do meu aplicativo. Apenas habilitei e estava funcionando.

BhushanVU
fonte
0

Passei muito tempo tentando encontrar a solução e, surpreendentemente, encontrei no final e foi muito engraçado quando descobri.

Aqui está o que você fará para recuperar a imagem que escolheu e retomar o trabalho :)

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

Sim, para resolver o problema, você só precisa dispensar o seletor normalmente, pois parece esta mensagem: "O instantâneo de uma visualização que não foi renderizada resulta em um instantâneo vazio. Certifique-se de que sua visualização tenha sido renderizada pelo menos uma vez antes de fazer o instantâneo ou após o instantâneo atualizações de tela. " impede que o seletor responda, mas você pode dispensá-lo e recuperar a imagem normalmente.

DevSherif
fonte
0

No meu caso foi relacionado a uma mudança de layout: o VC que apresenta o UIImagePickerViewControllertem a barra de status oculta, mas o UIImagePickerViewControllernão.

Então, resolvi escondendo a barra de status no UIImagePickerViewControllercomo é mostrado nesta resposta .

Kanobius
fonte
-1

Não respondendo diretamente à sua pergunta, mas você mencionou que tinha um aviso de memória, você pode estar armazenando a imagem bruta em uma propriedade que pode levar a um aviso de memória. Isso ocorre porque a imagem bruta ocupa aproximadamente 30 MB de memória. Notei um aviso de memória semelhante ao testar aplicativos no iOS6 que estavam na série iPhone 4. Ainda recebo este aviso quando os dispositivos foram atualizados para iOS7. Não há nenhum aviso de memória durante o teste no iPhone 5 da série no iOS7.

DevC
fonte
-5

Mudando

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

para

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

corrigiu o problema para mim.

Yuki
fonte