Instantánea de iOS 8 una vista que no se ha procesado da como resultado una instantánea vacía

228

En iOS 8 tengo problemas para capturar imágenes de la cámara hasta ahora estoy usando este código para

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

Pero en iOS 8 obtengo esto:

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.

He intentado con la solución proporcionada por This 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];

y esto

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

y esto

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

y esto

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

y esto

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

}];

¿alguna idea?

souvickcse
fuente
3
Tengo el mismo problema y aún más, este error bloquea mi aplicación de vez en cuando. Espero que la actualización 8.0.2 solucione este error. Cuando ejecuto mi aplicación en iOS7, funciona de maravilla sin ninguna advertencia estúpida. Parece que iOS 8 tiene un largo camino hacia la estabilidad.
NCFUSN
99
Evento con actualización 8.0.2 este problema aún persiste
ArdenDev
2
Estaba teniendo el mismo problema. Después de tomar la foto, estaba procesando algo en otro hilo. Después de mover el código al hilo principal, entonces todo estuvo bien. Es decir, mi código antes era: dispatch_async(dispatch_get_main_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{que cambié adispatch_async(dispatch_get_main_queue(), ^{
mikeyq6
99
El mismo problema ocurre en iOS 8.1
Raptor
12
También sucede en iOS 9.
Sebyddd

Respuestas:

131

Estoy bastante seguro de que esto es solo un error en iOS 8.0. Es reproducible con la más simple de las aplicaciones de POC que no hace más que intentar presentar una imagen UIImagePickerControllercomo la que estás haciendo arriba. Además, que yo sepa, no hay un patrón alternativo para mostrar el selector / cámara de imágenes. Incluso puede descargar la aplicación de muestra Uso de UIImagePickerController de Apple , ejecutarla y generará el mismo error de fábrica .

Dicho esto, la funcionalidad todavía funciona para mí. Aparte de la advertencia / error, ¿tiene problemas con el funcionamiento de su aplicación?

KevinH
fuente
2
Sí, probablemente sea un error, el código también funciona bien para mí.
souvickcse
44
@souvickcse También encuentro este error. Cada vez que ocurre, la vista previa de la imagen que aparece una vez que se ha tomado una nueva foto es completamente negra. Sin embargo, los botones "Volver a tomar" y "Usar foto" en la parte inferior de la pantalla todavía aparecen y funcionan correctamente. ¿Estás presenciando este mismo comportamiento?
Barry Beerman
3
@souvickcse Estoy usando la última línea de base del complemento de cámara phonegap ubicada aquí: github.com/apache/cordova-plugin-camera . Todo funciona bien con iOS 7.1 ejecutándose en un iPhone 5, pero no puedo encontrar una manera de hacerlo funcionar correctamente con iOS 8 en un iPhone 6.
Barry Beerman
2
Lo mismo para mí con iOS8.1 final
fvisticot
44
Todavía presente en iOS 9
el reverendo
45

Estuve luchando con este problema durante varias horas, ¡he leído todos los temas relevantes y descubrí que el error fue causado porque, bajo la configuración de privacidad de mi dispositivo, el acceso de la cámara a mi aplicación estaba bloqueado! Nunca he negado el acceso a la cámara y no sé cómo se bloqueó, ¡pero ese era el problema!

Pantelis Proios
fuente
44
No estoy seguro de si realmente funcionó para usted, pero no funcionó para mí. Solo espero que @KevinH sea correcto.
Deepak Thakur
44
No, el acceso a la cámara está activado para esa aplicación en mi caso. Pero sí creo que esto podría ser causado, aunque sea indirectamente, por la configuración: los cambios en la configuración a veces no surten efecto de inmediato, alguien en cupertino debe haber optimizado una llamada para sincronizar en algún lugar
Anton Tropashko
Esta sugerencia resolvió el problema por mí. Anteriormente había tocado "No permitir" cuando apareció el selector de cámara en mi aplicación. Pensé que me preguntaría cada vez que accedía a la cámara, pero no fue así. Tuve que ir a Configuración> Privacidad> Cámara y activar el control deslizante para mi aplicación. Entonces funcionó correctamente. Parece un poco tonto por parte de Apple no preguntar cada vez ...
John Contarino
exactamente, a veces no podemos pensar en el problema planteado para este tipo de errores. thx buddy muy útil
Mr.Javed Multani
La mejor opción es antes de usar la cámara para detectar si la capacidad está activa, y si no, alertar al usuario de que tomar fotografías no está disponible hasta que la cámara se active en la configuración. En iOS 10, es posible enviar al usuario a la configuración específica de la aplicación (era posible antes de iOS 8, pero no es posible en iOS 8 y 9, si recuerdo correctamente).
kindaian
33

No tengo suficientes puntos de reputación para comentar la respuesta de @ greg anterior, por lo que agregaré mis observaciones aquí. Tengo un proyecto Swift para iPad y iPhone. Tengo un método dentro de mi controlador de vista principal (bit relevante a continuación). Cuando pruebo esto en un teléfono, todo funciona correctamente y no se generan advertencias. Cuando lo ejecuto en un iPad, todo funciona correctamente, pero veo la advertencia sobre la captura de la vista. Sin embargo, lo interesante es que cuando ejecuto un iPad sin usar el controlador de popover, todo funciona correctamente sin advertencia. Desafortunadamente, Apple exige que el selector de imágenes se use dentro de un popover en iPad, si no se usa la cámara.

    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
fuente
Parece que esta es una sugerencia correcta porque tengo ese mensaje de error incluso con iOS 9.0.2. Tengo una aplicación solo para iPhone y cuando la ejecuto en mi iPad Mini veo ese mensaje cuando presento el selector de imágenes. Por alguna razón, iOS cree que ejecuto la aplicación iPad.
John Tracid
16

Me encontré con esto después de llamar a UIImagePickerController presentViewController: desde la devolución de llamada a un delegado UIAlertView. Resolví el problema presionando el presentViewController: cancele el seguimiento de ejecución actual usando 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];
    });
}
Greg
fuente
Esto es lo que me resolvió. Intentaba presentar el UIImagePickerController desde dentro del bloque de acción de UIAlertAction.
josefdlange
el alertView ha quedado en desuso, ¿funcionaría esto si uso el asíncrono dentro de una acción UIAlertViewController?
DrPatience
@DrPatience Claro. dispatch_async funciona en cualquier lugar que desee. No sé si es necesario (dependería de su código). Lea sobre GCD: tiene muchos usos.
Greg
12

Tuve este problema al animar algunas vistas y la aplicación entraría en modo de fondo y volvería. Lo manejé estableciendo una bandera isActive. Lo puse en NO en

- (void)applicationWillResignActive:(UIApplication *)application

y SÍ en

- (void)applicationDidBecomeActive:(UIApplication *)application

y animar o no animar mis puntos de vista en consecuencia. Se ocupó del problema.

byedissident
fuente
11

Tenía esto con una UIAlertControllerStyleActionSheet que le daba al usuario la opción de tomar una foto con la cámara o usar una de la biblioteca.

Intenté un punto de interrupción simbólico en el mensaje de error ingrese la descripción de la imagen aquí

Eso me mostró que el error se produce por el uso interno de un UICollectionView durante la presentación

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

ingrese la descripción de la imagen aquí

Lo arreglé estableciendo explícitamente el marco antes de presentar

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

Aquí está el método completo que funciona sin el error

-(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
fuente
10

Puede silenciar la advertencia "Capturar una vista" haciendo referencia a la viewpropiedad antes de presentar el controlador de vista. Al hacerlo, la vista se carga y permite que iOS la procese antes de tomar la instantánea.

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
fuente
Ese es un consejo casi increíblemente útil. ¡¡¡¡Gracias!!!! (En mi caso, sigo recibiendo la advertencia, pero la aplicación ya no se bloquea.)
Fattie
Sin embargo, cuando agrego un cameraOverlayView, desafortunadamente sigo teniendo este problema incluso cuando aplico este consejo.
Fattie
8

Para cualquiera que esté viendo un problema con una vista previa en negro después de la captura de imagen, ocultar la barra de estado después de que se muestre el UIPickerController parece solucionar el 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];
            }
        }];
Dan
fuente
1
totalmente salvado mi día! He intentado los métodos anteriores, ninguno funcionó. y esto funcionó
Stan
La solución no funciona. Creo que cuando capturamos una imagen en ese momento, StatusBar ya está oculto.
Mihir Oza
5

Encontré el mismo problema y probé todo. Tengo dos aplicaciones diferentes, una en Objective-C y otra en Swift, ambas tienen el mismo problema. El mensaje de error aparece en el depurador y la pantalla se vuelve negra después de la primera foto. Esto solo ocurre en iOS> = 8.0, obviamente es un error.

Encontré una solución difícil. Apague los controles de la cámara con imagePicker.showsCameraControls = false y cree su propio overlayView que tiene los botones que faltan. Hay varios tutoriales sobre cómo hacer esto. El extraño mensaje de error permanece, pero al menos la pantalla no se oscurece y tienes una aplicación que funciona.

Thomas Zimmer
fuente
Tuve exactamente el mismo problema que tú, mira mi respuesta a continuación.
Dan
5

Esto podría ser un error de ImagePickerController incorporado. Mi código funciona, pero ocasionalmente se bloquea en el iPhone 6 Plus.

He probado todas las soluciones sugeridas por otras respuestas, pero no tuve suerte. El problema finalmente se resolvió después de cambiar a JPSImagePickerController .

JonSlowCN
fuente
3

He intentado todo, mi problema fue que el selector de imágenes para la cámara y la biblioteca de fotos desapareció justo después de que aparecieron. Lo resolví con la siguiente línea (rápida)

imagePicker.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext
Waffeln
fuente
3

Estoy bastante seguro de que esto es solo un error en iOS 8.0. Es reproducible con la más simple de las aplicaciones POC que no hace más que intentar presentar un UIImagePickerController como lo está haciendo anteriormente. Además, que yo sepa, no hay un patrón alternativo para mostrar el selector / cámara de imágenes. Incluso puede descargar la aplicación de ejemplo Uso de UIImagePickerController de Apple, ejecutarla y generará el mismo error de fábrica.

Dicho esto, la funcionalidad todavía funciona para mí. Aparte de la advertencia / error, ¿tiene problemas con el funcionamiento de su aplicación?

Gaurav Patel
fuente
3

Si estamos usando UIImagePickerControllercomo propiedad, esta advertencia desaparecerá.supongamos que no estamos utilizando el resultado de UIImagePickerController, si estamos instanciando UIImagePickerControllerdentro de una función.

Antony Ouseph
fuente
2

Llamar a este método funcionó para mí. Colóquelo después de presentar su vista.

[yourViewBeingPresented.view layoutIfNeeded];
Poli
fuente
1

También encuentro el mismo problema y lo resolví comprobando si la cámara está disponible:

BOOL cameraAvailableFlag = [UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera];
    if (cameraAvailableFlag)
        [self performSelector:@selector(showcamera) withObject:nil afterDelay:0.3];
aftab muhammed khan
fuente
1
isSourceTypeAvailable devuelve true aunque haya denegado el acceso a la cámara para mi aplicación. La pantalla está en blanco si se niega el acceso a la cámara.
Καrτhικ
1

Me he encontrado con este problema. Cuando llamamos a la cámara y lanzamos las vistas, se produjo este problema. Por ejemplo, llame a una cámara y configure la vista nula en el método viewDidDisappear, este error se producirá ya que no hay devolución de llamada para el evento de la cámara. Asegúrese también de este caso para este error.

Gobi M
fuente
1

Recibí el mismo error, recibiendo un mensaje debajo de la consola al abrir la cámara.

'Hacer una instantánea de una vista que no se ha procesado da como resultado una instantánea vacía. Asegúrese de que su vista se haya procesado al menos una vez antes de la instantánea o instantánea después de las actualizaciones de la pantalla ".

Para mí, el problema era con el nombre para mostrar del paquete en el archivo Info.plist. De alguna manera estaba vacío, puse el nombre de mi aplicación allí y ahora funciona bien. No recibí ninguna alerta de permiso de cámara debido al nombre para mostrar del paquete vacío. bloqueó la vista de la representación.

el problema no estaba en la vista, pero presentándolo sin permiso. Puede verificarlo en configuración -> privacidad -> Cámara, si su aplicación no aparece en la lista, el problema puede ser el mismo.

Shabeer Ali
fuente
1

Estoy usando Phonegap, pero este hilo sigue apareciendo como el primero cuando busco en Google el mensaje de error.

Para mí, este problema desapareció al definir el tipo de imagen en PNG.

encodingType : Camera.EncodingType.PNG

Entonces toda la línea es:

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

Su millaje puede variar, pero eso fue el truco para mí.

Jannunen
fuente
1

Alternativamente, considere usar drawViewHierarchyInRect:

Rápido:

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

C objetivo:

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

    return image;
}

Ver también:

Eric
fuente
0

En mi caso (XCode 7 e iOS 9), uso UINavigationController"oculto", ¡así que tengo que agregar UINavigationControllerDelegatea la cámara actual o rodar y funciona como se supone que debe hacerlo! And pickerControllerDelegate.self¡tampoco muestra error!

Daniel Arantes Loverde
fuente