iOS 8 Schnappschuss Eine Ansicht, die nicht gerendert wurde, führt zu einem leeren Schnappschuss

228

In iOS 8 habe ich Probleme beim Aufnehmen von Bildern von der Kamera, bis jetzt verwende ich diesen Code für

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

Aber in iOS 8 bekomme ich folgendes:

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.

Ich habe mit dem von einer dritten Lösung versucht Dieser Beitrag mit

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

und das

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

und das

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

und das

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

und das

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

}];

irgendeine Idee?

souvickcse
quelle
3
Habe das gleiche Problem und außerdem stürzt dieser Fehler meine App von Zeit zu Zeit ab. Hoffe, Update 8.0.2 wird diesen Fehler beheben. Wenn ich meine App in iOS7 starte, funktioniert sie wie ein Zauber ohne dumme Warnungen. Es sieht so aus, als ob iOS 8 den langen Weg zur Stabilität hat.
NCFUSN
9
Ereignis mit 8.0.2 Update dieses Problem bleibt bestehen
ArdenDev
2
Ich hatte das gleiche Problem. Nachdem ich das Foto aufgenommen hatte, arbeitete ich in einem anderen Thread. Nachdem ich den Code in den Haupt-Thread verschoben hatte, war alles in Ordnung. Dh mein dispatch_async(dispatch_get_main_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{dispatch_async(dispatch_get_main_queue(), ^{
vorheriger
9
Das gleiche Problem tritt in iOS 8.1
Raptor
12
Passiert auch in iOS 9.
Sebyddd

Antworten:

131

Ich bin mir ziemlich sicher, dass dies nur ein Fehler in iOS 8.0 ist. Es ist mit der einfachsten POC-App reproduzierbar, die nichts weiter tut als zu versuchen, ein UIImagePickerControllerähnliches zu präsentieren, wie Sie es oben tun. Darüber hinaus gibt es meines Wissens kein alternatives Muster zur Anzeige des Bildwählers / der Bildkamera. Sie können sogar die Beispiel-App " Using UIImagePickerController" von Apple herunterladen , ausführen und den gleichen Fehler sofort generieren.

Trotzdem funktioniert die Funktionalität immer noch für mich. Haben Sie außer der Warnung / dem Fehler Probleme mit der Funktionsweise Ihrer App?

KevinH
quelle
2
Ja, wahrscheinlich ist es ein Fehler, Code funktioniert auch für mich gut.
Souvickcse
4
@souvickcse Ich stoße auch auf diesen Fehler. Immer wenn es auftritt, ist die Bildvorschau, die angezeigt wird, sobald ein neues Bild aufgenommen wurde, vollständig schwarz. Die Schaltflächen "Wiederaufnahme" und "Foto verwenden" am unteren Bildschirmrand werden jedoch weiterhin angezeigt und funktionieren ordnungsgemäß. Beobachten Sie dasselbe Verhalten?
Barry Beerman
3
@souvickcse Ich verwende die neueste Phonegap-Kamera-Plugin-Baseline, die sich hier befindet: github.com/apache/cordova-plugin-camera . Alles funktioniert gut mit iOS 7.1 auf einem iPhone 5, aber ich kann keinen Weg finden, es mit iOS 8 auf einem iPhone 6 richtig zum Laufen zu bringen.
Barry Beerman
2
Das gleiche gilt für mich mit iOS8.1 final
fvisticot
4
Immer noch in IOS 9 vorhanden
der Reverend
45

Ich hatte mehrere Stunden mit diesem Problem zu kämpfen. Ich habe jedes relevante Thema gelesen und festgestellt, dass der Fehler verursacht wurde, weil unter den Datenschutzeinstellungen meines Geräts der Kamerazugriff auf meine App blockiert war !!! Ich habe den Zugang zur Kamera nie verweigert und ich weiß nicht, wie sie blockiert wurde, aber das war das Problem!

Pantelis Proios
quelle
4
Ich bin mir nicht sicher, ob es tatsächlich bei Ihnen funktioniert hat, aber bei mir hat es nicht funktioniert. Ich hoffe nur, dass @KevinH richtig ist.
Deepak Thakur
4
Nein, in meinem Fall ist der Kamerazugriff für diese App aktiviert. Aber ich glaube, dies könnte indirekt durch Einstellungen verursacht werden: Änderungen an den Einstellungen werden manchmal nicht sofort wirksam, jemand in Cupertino muss einen Anruf optimiert haben, um irgendwo zu synchronisieren
Anton Tropashko
Dieser Vorschlag löste das Problem für mich. Ich hatte zuvor "Nicht zulassen" berührt, als die Kameraauswahl in meiner App angezeigt wurde. Ich dachte, es würde mich jedes Mal fragen, wenn ich auf die Kamera zugreife, aber das tat es nicht. Ich musste zu Einstellungen> Datenschutz> Kamera gehen und den Schieberegler für meine App aktivieren. Dann hat es richtig funktioniert. Scheint irgendwie albern von Apple, nicht jedes Mal zu fragen ...
John Contarino
Genau, manchmal können wir nicht glauben, dass ein Problem für diese Art von Fehlern aufgeworfen wurde. Danke Kumpel sehr hilfreich
Mr.Javed Multani
Die beste Option ist, bevor Sie die Kamera verwenden, um festzustellen, ob die Funktion aktiv ist, und wenn nicht, benachrichtigen Sie den Benutzer, dass das Aufnehmen von Bildern erst verfügbar ist, wenn die Kamera in den Einstellungen aktiviert ist. Unter iOS 10 ist es möglich, den Benutzer an die spezifischen App-Einstellungen zu senden (war vor iOS 8 möglich, aber unter iOS 8 und 9 nicht möglich, wenn ich mich richtig erinnere).
irgendwie
33

Ich habe nicht genügend Reputationspunkte, um die Antwort von @ greg oben zu kommentieren, daher werde ich meine Beobachtungen hier hinzufügen. Ich habe ein Swift-Projekt für iPad und iPhone. Ich habe eine Methode in meinem Hauptansichts-Controller (relevantes Bit unten). Wenn ich dies auf einem Telefon teste, funktioniert alles ordnungsgemäß und es werden keine Warnungen generiert. Wenn ich es auf einem iPad ausführe, funktioniert alles einwandfrei, aber ich sehe die Warnung bezüglich des Schnappschusses der Ansicht. Das Interessante ist jedoch, dass, wenn ich auf einem iPad ohne Verwendung des Popover-Controllers laufe, alles ohne Vorwarnung ordnungsgemäß funktioniert. Leider schreibt Apple vor, dass die Bildauswahl in einem Popover auf dem iPad verwendet werden muss, wenn die Kamera nicht verwendet wird.

    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);
        }
    });
dlw
quelle
Sieht so aus, als wäre dies ein korrekter Vorschlag, da ich diese Fehlermeldung auch unter iOS 9.0.2 habe. Ich habe nur eine iPhone-App und wenn ich sie auf meinem iPad Mini ausführe, wird diese Meldung bei der Präsentation der Bildauswahl angezeigt. Aus irgendeinem Grund glaubt iOS, dass ich die iPad-App starte.
John Tracid
16

Ich bin darauf gestoßen, nachdem ich UIImagePickerController presentViewController aufgerufen hatte: vom Rückruf an einen UIAlertView-Delegaten. Ich habe das Problem gelöst, indem ich den presentViewController gedrückt habe: Rufe den aktuellen Ausführungs-Trace mit dispatch_async auf.

- (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];
    });
}
greg
quelle
Das hat es für mich gelöst. Ich habe versucht, den UIImagePickerController aus dem Aktionsblock einer UIAlertAction heraus zu präsentieren.
Josefdlange
Die AlertView ist veraltet. Würde dies funktionieren, wenn ich stattdessen die asynchrone Aktion in einer UIAlertViewController-Aktion verwende?
DrPatience
@ DrPatience Sicher. dispatch_async funktioniert beliebig. Ich weiß nicht, dass es notwendig ist (würde von Ihrem Code abhängen). Lesen Sie mehr über GCD - es hat sehr viele Verwendungsmöglichkeiten.
Greg
12

Ich hatte dieses Problem beim Animieren einiger Ansichten und die App ging in den Hintergrundmodus und kehrte zurück. Ich habe es gehandhabt, indem ich ein Flag isActive gesetzt habe. Ich habe es auf NEIN gesetzt

- (void)applicationWillResignActive:(UIApplication *)application

und JA in

- (void)applicationDidBecomeActive:(UIApplication *)application

und meine Ansichten entsprechend animieren oder nicht animieren. Kümmerte sich um das Problem.

byedissident
quelle
11

Ich hatte dies mit einem UIAlertControllerStyleActionSheet, das dem Benutzer die Möglichkeit gab, ein Foto mit der Kamera aufzunehmen oder eines aus der Bibliothek zu verwenden.

Ich habe versucht, einen symbolischen Haltepunkt für die Fehlermeldung festzulegen Geben Sie hier die Bildbeschreibung ein

Das hat mir gezeigt, dass der Fehler durch die interne Verwendung einer UICollectionView während der Präsentation verursacht wird

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

Geben Sie hier die Bildbeschreibung ein

Ich habe dies behoben, indem ich den Rahmen vor dem Präsentieren explizit eingestellt habe

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

Hier ist die vollständige Methode, die ohne Fehler funktioniert

-(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:^(){
}];}
Yedy
quelle
10

Sie können die Warnung "Snapshotting einer Ansicht" stumm schalten, indem Sie auf die viewEigenschaft verweisen, bevor Sie den Ansichts-Controller anzeigen. Dadurch wird die Ansicht geladen und iOS kann sie rendern, bevor der Schnappschuss erstellt wird.

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];
Steve Shepard
quelle
Das ist ein fast unglaublich nützlicher Tipp. Danke dir!!!! (In meinem Fall bekomme ich immer noch die Warnung, aber die App stürzt nicht mehr ab.)
Fattie
Wenn ich jedoch ein hinzufüge cameraOverlayView, tritt dieses Problem leider auch dann noch auf, wenn ich diesen Tipp anwende.
Fattie
8

Für alle, die nach der Bildaufnahme ein Problem mit einer schwarzen Vorschau sehen, scheint das Ausblenden der Statusleiste nach dem Anzeigen des UIPickerControllers das Problem zu beheben.

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];
            }
        }];
Dan
quelle
1
Ich habe oben Methoden ausprobiert, keine hat funktioniert. Und das hat funktioniert
Stan
Lösung funktioniert nicht. Ich denke, wenn wir zu diesem Zeitpunkt ein Bild aufnehmen, ist die Statusleiste bereits ausgeblendet.
Mihir Oza
5

Ich fand das gleiche Problem und versuchte alles. Ich habe zwei verschiedene Apps, eine in Objective-C und eine in Swift - beide haben das gleiche Problem. Die Fehlermeldung wird im Debugger angezeigt und der Bildschirm wird nach dem ersten Foto schwarz. Dies passiert nur in iOS> = 8.0, offensichtlich ist es ein Fehler.

Ich habe eine schwierige Problemumgehung gefunden. Schalten Sie die Kamerasteuerung mit imagePicker.showsCameraControls = false aus und erstellen Sie eine eigene OverlayView mit den fehlenden Schaltflächen. Es gibt verschiedene Tutorials dazu. Die seltsame Fehlermeldung bleibt bestehen, aber zumindest wird der Bildschirm nicht schwarz und Sie haben eine funktionierende App.

Thomas Zimmer
quelle
Ich hatte genau das gleiche Problem wie Sie, siehe meine Antwort unten.
Dan
5

Dies könnte ein Fehler des integrierten ImagePickerController sein. Mein Code funktioniert, stürzt aber gelegentlich auf dem iPhone 6 Plus ab.

Ich habe alle von anderen Antworten vorgeschlagenen Lösungen ausprobiert, aber es gab kein Glück. Problem nach dem Wechsel zu JPSImagePickerController endgültig gelöst .

JonSlowCN
quelle
3

Ich habe alles versucht, mein Problem war, dass der Bildwähler für die Kamera und die Fotobibliothek sofort nach dem Anzeigen verschwand. Ich habe es mit der folgenden Zeile gelöst (schnell)

imagePicker.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext
Waffeln
quelle
3

Ich bin mir ziemlich sicher, dass dies nur ein Fehler in iOS 8.0 ist. Es ist mit der einfachsten POC-App reproduzierbar, die lediglich versucht, einen UIImagePickerController wie oben zu präsentieren. Darüber hinaus gibt es meines Wissens kein alternatives Muster zur Anzeige des Bildwählers / der Bildkamera. Sie können sogar Apples Beispiel-App Using UIImagePickerController herunterladen, ausführen und den gleichen Fehler sofort generieren.

Trotzdem funktioniert die Funktionalität immer noch für mich. Haben Sie außer der Warnung / dem Fehler Probleme mit der Funktionsweise Ihrer App?

Gaurav Patel
quelle
3

Wenn wir die verwenden UIImagePickerController als Eigenschaft verwenden, verschwindet diese Warnung.Nehmen wir an, dass wir das Ergebnis von nicht verwenden UIImagePickerController, wenn wir das UIImagePickerControllerinnerhalb einer Funktion instanziieren .

Antony Ouseph
quelle
2

Das Aufrufen dieser Methode hat bei mir funktioniert. Platzieren Sie es, nachdem Sie Ihre Ansicht präsentiert haben.

[yourViewBeingPresented.view layoutIfNeeded];
Bobby
quelle
1

Ich habe auch das gleiche Problem und habe es behoben, indem ich überprüft habe, ob die Kamera verfügbar ist:

BOOL cameraAvailableFlag = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];
    if (cameraAvailableFlag)
        [self performSelector:@selector(showcamera) withObject:nil afterDelay:0.3];
Aftab Muhammed Khan
quelle
1
isSourceTypeAvailable gibt true zurück, obwohl ich den Zugriff auf die Kamera für meine App verweigert habe. Die Anzeige ist leer, wenn der Kamerazugriff verweigert wird.
Καrτhικ
1

Ich bin auf dieses Problem gestoßen. Wenn wir die Kamera aufrufen und die Ansichten freigeben, entsteht dieses Problem. Rufen Sie beispielsweise eine Kamera auf und setzen Sie in der viewDidDisappear-Methode die Ansicht auf Null. Dieser Fehler tritt auf, da für das Kameraereignis kein Rückruf erfolgt. Stellen Sie auch für diesen Fehler sicher, dass dieser Fall vorliegt.

Gobi M.
quelle
1

Ich habe den gleichen Fehler, als ich beim Öffnen der Kamera eine Balgmeldung in der Konsole erhielt.

'Schnappschuss einer Ansicht, die nicht gerendert wurde, führt zu einem leeren Schnappschuss. Stellen Sie sicher, dass Ihre Ansicht mindestens einmal gerendert wurde, bevor Sie einen Schnappschuss oder einen Schnappschuss nach Bildschirmaktualisierungen erstellen. '

Für mich war das Problem mit dem Bundle-Anzeigenamen in der Datei Info.plist. Es war irgendwie leer. Ich habe meinen App-Namen dort abgelegt und jetzt funktioniert es einwandfrei. Ich habe wegen des leeren Bundle-Anzeigenamens.it keine Benachrichtigung über die Kameraberechtigung erhalten blockierte das Rendern der Ansicht.

Das Problem lag nicht in der Ansicht, sondern in der Darstellung ohne Erlaubnis. Sie können es unter Einstellungen -> Datenschutz -> Kamera überprüfen, wenn Ihre App dort nicht aufgeführt ist. Das Problem ist möglicherweise dasselbe.

Shabeer Ali
quelle
1

Ich verwende Phonegap, aber dieser Thread wird immer wieder als erster angezeigt, wenn über die Fehlermeldung gegoogelt wird.

Für mich wurde dieses Problem behoben, indem der Imagetyp für PNG definiert wurde.

encodingType : Camera.EncodingType.PNG

Die ganze Zeile lautet also:

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

Ihr Kilometerstand kann variieren, aber das hat mir geholfen.

Jannunen
quelle
1

Alternativ können Sie Folgendes verwenden drawViewHierarchyInRect:

Schnell:

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

Ziel c:

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

    return image;
}

Siehe auch:

Eric
quelle
0

In meinem Fall (XCode 7 und iOS 9) verwende ich UINavigationController"versteckt", also muss ich die UINavigationControllerDelegateaktuelle Kamera oder Rolle hinzufügen und es funktioniert so, wie es soll! And pickerControllerDelegate.selfzeigt auch keinen Fehler an!

Daniel Arantes Loverde
quelle