iOS 8 L'istantanea di una vista che non è stata renderizzata genera un'istantanea vuota


228

In iOS 8 ho problemi a catturare immagini dalla fotocamera fino ad ora sto usando questo codice per

UIImagePickerController *controller=[[UIImagePickerController alloc] init];
controller.videoQuality=UIImagePickerControllerQualityTypeMedium;
controller.delegate=(id)self;
controller.sourceType=UIImagePickerControllerSourceTypeCamera;
[self presentViewController:controller animated:YES completion:nil];

Ma in iOS 8 sto ottenendo questo:

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.

Ho provato con la soluzione fornita da questo post con

@property (strong,nonatomic)UIImagePickerController *controller;

_controller=[[UIImagePickerController alloc] init];
_controller.videoQuality=UIImagePickerControllerQualityTypeMedium;
_controller.delegate=(id)self;
_controller.sourceType=UIImagePickerControllerSourceTypeCamera;
_[self presentViewController:controller animated:YES completion:nil];

e questo

...
controller.modalPresentationStyle=UIModalPresentationFullScreen;
or
controller.modalPresentationStyle=UIModalPresentationCurrentContext;
...

e questo

double delayInSeconds = 0.1;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    [self presentViewController:controller animated:YES completion:nil];
});

e questo

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

e questo

[self presentViewController:controller animated:YES completion:^{

}];

qualche idea?


3
Hanno lo stesso problema e inoltre questo bug si blocca la mia app di volta in volta. Spero che l'aggiornamento 8.0.2 risolva questo errore. Quando eseguo la mia app in iOS7 funziona come un incantesimo senza stupidi avvisi. Sembra che iOS 8 abbia una lunga strada per la stabilità.
NCFUSN,

9
Evento con aggiornamento 8.0.2 questo problema persiste ancora
ArdenDev

2
Avevo lo stesso problema. Dopo aver scattato la foto, stavo facendo qualche elaborazione in un altro thread. Dopo aver spostato il codice nel thread principale, quindi tutto era ok. Cioè, il mio codice prima era: dispatch_async(dispatch_get_main_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{che ho cambiato indispatch_async(dispatch_get_main_queue(), ^{
mikeyq6

9
Lo stesso problema si verifica in iOS 8.1
Raptor

12
Succede anche in iOS 9.
Sebyddd,

Risposte:


131

Sono abbastanza sicuro che questo sia solo un bug in iOS 8.0. È riproducibile con la più semplice delle app POC che non fa altro che tentare di presentare qualcosa UIImagePickerControllercome quello che stai facendo sopra. Inoltre, per quanto ne so, non esiste un modello alternativo per visualizzare il selettore di immagini / fotocamera. Puoi persino scaricare l' app di esempio Apple che utilizza UIImagePickerController , eseguirla e genererà lo stesso errore .

Detto questo, la funzionalità funziona ancora per me. Oltre all'avviso / errore, hai problemi con il funzionamento della tua app?


2
Sì, probabilmente è un bug, il codice funziona bene anche per me.
souvickcse,

4
@souvickcse Riscontro anche questo errore. Ogni volta che si verifica, l'anteprima dell'immagine che si apre una volta che una nuova foto è stata scattata è completamente nera. Tuttavia, i pulsanti "Re-Take" e "Usa foto" nella parte inferiore dello schermo appaiono ancora e funzionano correttamente. Stai assistendo a questo stesso comportamento?
Barry Beerman,

3
@souvickcse Sto utilizzando la più recente linea base di plug-in per fotocamere phonegap che si trova qui: github.com/apache/cordova-plugin-camera . Funziona tutto bene con iOS 7.1 in esecuzione su un iPhone 5 ma non riesco a trovare un modo per farlo funzionare correttamente usando iOS 8 su un iPhone 6.
Barry Beerman,

2
Lo stesso per me con iOS 8.1 finale
fvisticot

4
Ancora presente in IOS 9
il reverendo il

45

Sono stato alle prese con questo problema per diverse ore, ho letto tutti gli argomenti rilevanti e ho scoperto che l'errore era causato perché sotto le impostazioni di privacy del mio dispositivo, l'accesso alla mia app era bloccato !!! Non ho mai negato l'accesso alla videocamera e non so come sia stato bloccato, ma quello era il problema!


4
non sono sicuro che abbia funzionato davvero per te, ma non ha funzionato per me. Spero solo che @KevinH sia corretto.
Deepak Thakur,

4
No, nel mio caso l'accesso alla telecamera è ATTIVATO per quell'app. Ma credo che ciò possa essere causato anche se indirettamente dalle impostazioni: le modifiche alle impostazioni a volte non hanno effetto immediato, qualcuno a Cupertino deve aver ottimizzato una chiamata per sincronizzare da qualche parte
Anton Tropashko

Questo suggerimento ha risolto il problema per me. In precedenza avevo toccato "Non consentire" quando il selettore della fotocamera è apparso nella mia app. Ho pensato che mi avrebbe chiesto ogni volta che ho avuto accesso alla videocamera, ma non è stato così. Ho dovuto andare su Impostazioni> Privacy> Fotocamera e attivare il dispositivo di scorrimento per la mia app. Quindi ha funzionato correttamente. Sembra sciocco da parte di Apple non chiedere ogni volta ...
John Contarino,

esattamente, a volte non possiamo pensare che sia stato sollevato un problema per questo tipo di errori. grazie amico molto utile
Mr.Javed Multani

L'opzione migliore è prima di utilizzare la fotocamera per rilevare se la funzionalità è attiva e, in caso contrario, avvisare l'utente che scattare foto non è disponibile fino a quando la fotocamera non viene attivata sulle impostazioni. Su iOS 10, è possibile inviare l'utente alle impostazioni dell'app specifiche (era possibile prima di iOS 8, ma non era possibile su iOS 8 e 9, se ricordo bene).
kindaian,

33

Non ho abbastanza punti reputazione per commentare la risposta di @ greg sopra, quindi aggiungerò le mie osservazioni qui. Ho un progetto Swift sia per iPad che per iPhone. Ho un metodo all'interno del mio controller di visualizzazione principale (relativo bit di seguito). Quando provo questo su un telefono, tutto funziona correttamente e non vengono generati avvisi. Quando lo eseguo su un iPad, tutto funziona correttamente, ma visualizzo l'avviso relativo all'istantanea della vista. Il punto interessante, tuttavia, è che quando corro su un iPad senza usare il controller popover, tutto funziona correttamente senza preavviso. Sfortunatamente, Apple impone che il selettore di immagini debba essere utilizzato all'interno di un popover su iPad, se la fotocamera non viene utilizzata.

    dispatch_async(dispatch_get_main_queue(), {
        let imagePicker: UIImagePickerController = UIImagePickerController();
        imagePicker.sourceType = UIImagePickerControllerSourceType.SavedPhotosAlbum;
        imagePicker.mediaTypes = [kUTTypeImage];
        imagePicker.allowsEditing = false;
        imagePicker.delegate = self;

        if(UIDevice.currentDevice().userInterfaceIdiom == .Pad){ // on a tablet, the image picker is supposed to be in a popover
            let popRect: CGRect = buttonRect;
            let popover: UIPopoverController = UIPopoverController(contentViewController: imagePicker);
            popover.presentPopoverFromRect(popRect, inView: self.view, permittedArrowDirections: UIPopoverArrowDirection.Up, animated: true);
        }else{
            self.presentViewController(imagePicker, animated: true, completion: nil);
        }
    });

Sembra che questo sia un suggerimento corretto perché sto ricevendo quel messaggio di errore anche con iOS 9.0.2. Ho solo l'app per iPhone e quando la eseguo sul mio iPad Mini vedo quel messaggio quando presenti il ​​selettore di immagini. Per qualche ragione iOS pensa che io esegua l'app per iPad.
John Tracid,

16

Mi sono imbattuto in questo dopo aver chiamato UIImagePickerController presentViewController: dal callback a un delegato UIAlertView. Ho risolto il problema spingendo presentViewController: annullare la traccia di esecuzione corrente utilizzando dispatch_async.

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
    dispatch_async(dispatch_get_main_queue(), ^{
        UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
        imagePickerController.delegate = self;

        if (buttonIndex == 1)
            imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
        else
            imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;

        [self presentViewController: imagePickerController
                           animated: YES
                         completion: nil];
    });
}

Questo è ciò che ha risolto per me. Stavo tentando di presentare UIImagePickerController dall'interno del blocco d'azione di UIAlertAction.
josefdlange,

l'avvisoView è stato deprecato, funzionerebbe se utilizzassi invece l'asincronizzazione all'interno di un'azione UIAlertViewController?
DrPatience,

@DrPatience Certo. dispatch_async funziona dove vuoi tu. Non so che è necessario (dipende dal tuo codice). Leggi su GCD - ha molti usi.
Greg

12

Ho avuto questo problema durante l'animazione di alcune visualizzazioni e l'app andava in modalità background e tornava. L'ho gestito impostando un flag isActive. L'ho impostato su NO in

- (void)applicationWillResignActive:(UIApplication *)application

e SÌ in

- (void)applicationDidBecomeActive:(UIApplication *)application

e animare o non animare le mie opinioni di conseguenza. Si è preso cura del problema.


11

Ho avuto questo con un UIAlertControllerStyleActionSheet dando all'utente la possibilità di scattare una foto con la fotocamera o usarne una dalla libreria.

Ho provato un punto di interruzione simbolico sul messaggio di errore inserisci qui la descrizione dell'immagine

Ciò mi ha mostrato che l'errore è prodotto dall'uso interno di un UICollectionView durante la presentazione

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

inserisci qui la descrizione dell'immagine

Ho risolto questo problema impostando in modo esplicito il frame prima di presentarlo

[alert setPreferredContentSize: alert.view.frame.size];

Ecco il metodo completo che funziona senza l'errore

-(void)showImageSourceAlertFromSender:(id)sender{
UIButton *senderButton = (UIButton*)sender;
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *cameraAction = [UIAlertAction actionWithTitle:@"Camera" style:UIAlertActionStyleDefault
                                                     handler:^(UIAlertAction *action) {
                                                         [self takePhoto];
                                                     }];
UIAlertAction *libraryAction = [UIAlertAction actionWithTitle:@"Library" style:UIAlertActionStyleDefault
                                                      handler:^(UIAlertAction *action) {
                                                          [self selectPhotoFromLibraryFromSender:sender];
                                                      }];
[alert addAction:cameraAction];
[alert addAction:libraryAction];
alert.popoverPresentationController.delegate = self;
alert.popoverPresentationController.sourceRect = senderButton.frame;
alert.popoverPresentationController.sourceView = self.view;

[alert setPreferredContentSize: alert.view.frame.size];

[self presentViewController:alert animated:YES completion:^(){
}];}

10

È possibile silenziare l'avviso "Snapshot di una vista" facendo riferimento alla viewproprietà prima di presentare il controller della vista. In questo modo la vista si carica e consente a iOS di renderla prima di scattare l'istantanea.

UIAlertController *controller = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
controller.modalPresentationStyle = UIModalPresentationPopover;
controller.popoverPresentationController.barButtonItem = (UIBarButtonItem *)sender;

... setup the UIAlertController ... 

[controller view]; // <--- Add to silence the warning.

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

Questo è un suggerimento quasi incredibilmente utile. Grazie!!!! (Nel mio caso, ricevo ancora l'avviso, ma l'app non si blocca più.)
Fattie

Tuttavia, quando aggiungo un cameraOverlayView, purtroppo ho ancora questo problema anche quando applico questo suggerimento.
Fattie,

8

Per chiunque stia riscontrando un problema con un'anteprima nera dopo l'acquisizione dell'immagine, nascondere la barra di stato dopo la visualizzazione di UIPickerController sembra risolvere il problema.

UIImagePickerControllerSourceType source = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] ? UIImagePickerControllerSourceTypeCamera : UIImagePickerControllerSourceTypeSavedPhotosAlbum;
UIImagePickerController *cameraController = [[UIImagePickerController alloc] init];
        cameraController.delegate = self;
        cameraController.sourceType = source;
        cameraController.allowsEditing = YES;
        [self presentViewController:cameraController animated:YES completion:^{
            //iOS 8 bug.  the status bar will sometimes not be hidden after the camera is displayed, which causes the preview after an image is captured to be black
            if (source == UIImagePickerControllerSourceTypeCamera) {
                [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
            }
        }];

1
ho completamente salvato la mia giornata! Ho provato i metodi sopra, nessuno ha funzionato e questo ha funzionato
Stan

La soluzione non funziona. Penso che quando catturiamo un'immagine in quel momento StatusBar già nascosto.
Mihir Oza,

5

Ho trovato lo stesso problema e ho provato di tutto. Ho due app diverse, una in obiettivo-C e una in rapido - entrambi hanno lo stesso problema. Il messaggio di errore viene visualizzato nel debugger e lo schermo diventa nero dopo la prima foto. Questo succede solo in iOS> = 8.0, ovviamente è un bug.

Ho trovato una soluzione alternativa difficile. Spegni i controlli della fotocamera con imagePicker.showsCameraControls = false e crea il tuo overlayView con i pulsanti mancanti. Esistono vari tutorial su come eseguire questa operazione. Lo strano messaggio di errore rimane, ma almeno lo schermo non diventa nero e hai un'app funzionante.


Ho avuto lo stesso identico problema, vedi la mia risposta di seguito.
Dan,

5

Potrebbe trattarsi di un bug di ImagePickerController integrato. Il mio codice funziona, ma a volte si blocca su iPhone 6 Plus.

Ho provato tutte le soluzioni suggerite da altre risposte ma non ho avuto fortuna. Problema finalmente risolto dopo il passaggio a JPSImagePickerController .


3

Ho provato di tutto, il mio problema era che il selettore di immagini per la fotocamera e la libreria di foto erano scomparsi subito dopo averli mostrati. L'ho risolto con la seguente riga (veloce)

imagePicker.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext

3

Sono abbastanza sicuro che questo sia solo un bug in iOS 8.0. È riproducibile con la più semplice delle app POC che non fa altro che tentare di presentare un UIImagePickerController come stai facendo sopra. Inoltre, per quanto ne so, non esiste un modello alternativo per visualizzare il selettore di immagini / fotocamera. Puoi persino scaricare l'app di esempio Using UIImagePickerController di Apple, eseguirla e genererà lo stesso errore immediatamente.

Detto questo, la funzionalità funziona ancora per me. Oltre all'avviso / errore, hai problemi con il funzionamento della tua app?


3

Se stiamo usando il UIImagePickerController come proprietà, questo avviso scompare.supponiamo che non stiamo usando il risultato di UIImagePickerController, se stiamo istanziando UIImagePickerControllerall'interno di una funzione.


2

Chiamare questo metodo ha funzionato per me. Posizionalo dopo aver presentato la tua vista.

[yourViewBeingPresented.view layoutIfNeeded];

1

Inoltre riscontro lo stesso problema e l'ho risolto controllando se la fotocamera è disponibile:

BOOL cameraAvailableFlag = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];
    if (cameraAvailableFlag)
        [self performSelector:@selector(showcamera) withObject:nil afterDelay:0.3];

1
isSourceTypeAvailable restituisce true anche se ho negato l'accesso alla videocamera per la mia app. Il display è vuoto se l'accesso alla telecamera è negato.
Καrτhικ,

1

Mi sono imbattuto in questo problema. Quando chiamiamo la fotocamera e rilasciamo le visualizzazioni ha prodotto questo problema. Per un esempio, chiamare una telecamera e impostare view nil nel metodo viewDidDisappear questo errore si presenterà poiché non è presente il callback per l'evento della telecamera. Assicurati anche di questo caso per questo errore.


1

Ho avuto lo stesso bug, ricevendo un messaggio nella console mentre aprivo la fotocamera.

'L'istantanea di una vista che non è stata renderizzata risulta in un'istantanea vuota. Assicurati che la tua vista sia stata renderizzata almeno una volta prima dell'istantanea o dell'istantanea dopo gli aggiornamenti dello schermo. "

Per me il problema era con il nome visualizzato del pacchetto in Info.plist file.it era vuoto in qualche modo, ho messo il nome della mia app lì e ora funzionava bene.Non ho ricevuto alcun avviso di autorizzazione della fotocamera a causa del nome visualizzato del pacchetto vuoto.it bloccato il rendering della vista.

il problema non riguardava la visualizzazione ma presentandolo senza autorizzazione. Puoi verificarlo in Impostazioni -> Privacy -> Videocamera, se l'app non elencata lì potrebbe essere lo stesso.


1

Sto usando Phonegap, ma questo thread continua a venire come il primo quando si cerca su Google il messaggio di errore.

Per me questo problema è andato via definendo il tipo di immagine in PNG.

encodingType : Camera.EncodingType.PNG

Quindi l'intera linea essendo:

 navigator.camera.getPicture(successFunction, failFunction, { encodingType : Camera.EncodingType.PNG, correctOrientation:true, sourceType : Camera.PictureSourceType    .PHOTOLIBRARY, quality: 70, allowEdit : false , destinationType: Camera.DestinationType.DATA_URL});

Il tuo chilometraggio può variare, ma quello ha funzionato per me.


1

In alternativa, considera l'utilizzo di drawViewHierarchyInRect:

Swift:

extension UIImage{

    class func renderUIViewToImage(viewToBeRendered: UIView) -> UIImage
    {
        UIGraphicsBeginImageContextWithOptions(viewToBeRendered.bounds.size, true, 0.0)
        viewToBeRendered.drawViewHierarchyInRect(viewToBeRendered.bounds, afterScreenUpdates: true)
        viewToBeRendered.layer.renderInContext(UIGraphicsGetCurrentContext()!)

        let finalImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return finalImage
    }
}

Objective-C:

- (UIImage *)snapshot:(UIView *)view
{
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, YES, 0);
    [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

Vedi anche:


0

Nel mio caso (XCode 7 e iOS 9), utilizzo UINavigationController"nascosto", quindi devo aggiungere la UINavigationControllerDelegatefotocamera o il rullo presenti e funziona come dovrebbe! And pickerControllerDelegate.selfnon visualizza neanche l'errore!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.