iOS 7 UIImagePickerController tiene vista previa en negro

Tengo un UIImagePickerController que se llama con la cámara sourceType y el 80% de las veces aparece una vista previa en negro. Si espero, digamos unos 30 segundos, obtengo una buena vista previa y estará bien durante aproximadamente el 50% del tiempo, luego puede volver a romperse.

La imagen en cuestión es muy similar a esto. La cámara iDevice muestra negro en lugar de vista previa

Otras personas implican que GCD podría estar causando algunos problemas con la cámara, y que las actualizaciones de la interfaz de usuario mientras se carga el selector de imágenes lo rompen. Puse un candado en cada bloque de GCD que llama al hilo principal para este propósito.

Este es un ejemplo de una imagen que gira para simular un indicador de actividad.

-(void)animateLoadingImage { if (isMainThreadBlocked) { return; } self.radians += M_PI_4 / 2; [UIView beginAnimations:@"progress rotation" context:nil]; [UIView setAnimationDuration:.1]; self.loadingImageView.transform = CGAffineTransformMakeRotation(self.radians); [UIView commitAnimations]; } 

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

Esto muestra SIEMPRE cuando trato de abrir el controlador del selector, pero lo muestra incluso si la cámara muestra la vista previa correctamente. No creo que el error esté por aquí, pero esto también me molesta mucho.

No parece haber una buena respuesta para esto en ninguna parte en línea, así que tuve que esforzarme mucho para resolverlo.

Estoy usando ARC (como probablemente la mayoría de los otros en la actualidad), por lo que la respuesta anterior realmente no me ayudó.

Este problema de la cámara negra sucede como un efecto secundario de hacer cosas UIKit fuera del hilo principal en iOS 7. En general, las operaciones UIKit de fondo resultan en todo tipo de cosas extrañas que ocurren en iOS 7 (la memoria no se desasigna rápidamente, los enganches de rendimiento extraños y el problema de la cámara negra).

Para evitar esto, no debe hacer CUALQUIER cosa UIKit en hilos de fondo.

Cosas que no puede hacer en los hilos de fondo: – Asignar / inicializar UIViews y subclases – Modificar UIViews y subclases (por ejemplo, establecer el marco, establecer atributos .image / .text, etc.).

Ahora, el problema de hacer esto en el hilo principal es que puede interferir con el rendimiento de la interfaz de usuario, por lo que ves todas estas soluciones de carga de fondo de iOS 6 que NO funcionan de manera óptima en iOS 7 (es decir, causan la cámara negra problema, entre otras cosas).

Hay dos cosas que hice para corregir el rendimiento y evitar los malos efectos de las operaciones de UIKit en segundo plano: – Precrear e inicializar todos los UIImages en un hilo de fondo. Lo único que deberías hacer con UIImages en el hilo principal es establecer “imageView.image = preloadedImageObject;” – Reutilizar vistas siempre que sea posible. Hacer [[UIView alloc] init] en el hilo principal aún puede ser problemático si lo haces en un cellForRowAtIndex o en otra situación donde la capacidad de respuesta es muy importante.

¡La mejor de las suertes! Puede probar cómo lo hace supervisando el uso de la memoria mientras se ejecuta su aplicación. Fondo UIKit => uso de la memoria escalada rápidamente.

Durante uno de mis proyectos recientes tuve este mismo problema (o similar), es decir, la vista previa de la cámara que muestra una pantalla en negro al usar UIImagePickerController en iOS7 (iPad).

Lo que descubrí es que GCD en sí mismo no es el problema. El problema ocurre cuando intentas usar cualquier cosa desde el marco de UIKit en un hilo que no sea el hilo principal (como parte de una NSOperation).

Antes que nada, permítanme comenzar diciendo que es claro para mí que no deberían hacer esto para empezar. En mi caso específico, sin embargo, no tuve elección. Como creo que hay muchas posibilidades de que otras personas experimenten el mismo extraño comportamiento de la cámara UIImagePickerController con la misma causa, inventé un código de ejemplo muy simple que explica lo que está sucediendo.

Puede encontrarlo aquí: https://github.com/idamediafoundry/CameraTest

ViewController muestra 2 botones simples. Uno llama a UIImagePickerController, que muestra la cámara, el otro inicia algunas operaciones GCD haciendo una tarea simple. Si abre la cámara, todo funciona bien. Si primero comienza las operaciones y luego abre la cámara, se produce el problema de la vista previa en negro.

De nuevo, no debes llamar a UIKit en nada que no sea el hilo principal. Pero no creo que sea normal que al romper esta regla, la cámara funcione mal al abrirla más tarde en el hilo principal como parte de un flujo completamente diferente, ¿no?

Espero que esto ayude.

Tuve el mismo problema, pero la aplicación nunca mostraba la alerta para otorgar permiso para acceder a las fotos, y nunca aparecería en Configuración-> Privacidad-> Fotos como si hubiera pedido permiso. Simplemente mostraría la pantalla en negro sin un aviso de permiso.

Finalmente tracé esto a info.plist.

enter image description here

Como resultado, si agrega la clave “Nombre de visualización del paquete” a info.plist y deja el valor en blanco, la alerta de permiso nunca se mostrará. Parece que la alerta de permisos extrae este valor para mostrarse en la alerta, y si lo deja en blanco, simplemente no mostrará la alerta.

Si tiene esto en su lista sin valor, podría estar causando una vista previa en negro.

EDITAR: Estaba experimentando este problema con algunos dispositivos y no con otros, con mis pruebas de los 3 dispositivos iPhone 6 con los que probé y el iPhone 5s no mostraba la alerta y se colgaba de la pantalla en negro. Un iPhone 4s y iPhone 6S + mostraron la alerta y funcionó como se esperaba.

En primer lugar, este problema parece en parte culpa de Apple y los desarrolladores, probablemente más en el lado de los desarrolladores. Pude hacer que mi aplicación produjera una imagen de vista previa negra al alternar entre la aplicación de cámara nativa y el uso de mi propia aplicación del modo de cámara UIImagePickerController . No fue consistente pero hice que ocurriera haciendo esos pasos repetidamente durante unas 5-15 veces, eventualmente se convertiría en una vista previa negra.

Por otro lado, pude abordar este problema mediante la refacturación de mi propio código. No necesité construir una cámara personalizada como otras pudieron haber hecho con AVFoundation, más bien, eliminé todas las memory leaks potenciales / válidas de mi código. Asegúrate de probar tu aplicación con Instruments, deshacerte de cualquier fuga. Limpie UIImagePickerController también, que puede diferir según el uso de ARC o no. Después de mi refactor, el problema con la vista previa en negro desapareció. Creo que una pérdida de memoria en tu aplicación es la causa de que la vista previa del video se vuelva negra después de algún tiempo.

Por último, tuve otra aplicación que usa el escáner zxing, que usa AVFoundation para decodificar imágenes desde la transmisión de vista previa en vivo … este fue muy complicado de arreglar, era ARC mezclado con no-arco (zxing no-arco). Tuve que refactorizar un montón más de código ya que la jerarquía de view / UIViewController era mucho más compleja y conseguir la verdadera clave para que el objeto real que contiene la sesión de AVFoundation fuera dealloc. Después de un día de refactorización, este problema desapareció, así que sí, tapar las pérdidas de memoria fue la respuesta en ambos casos del problema de la vista previa de la imagen negra en iOS 7.

En mi caso, tuve que mover algunos métodos al hilo principal.

Mi aplicación crea una nueva Imagen con un nuevo contexto, puedo crear el nuevo contexto en un hilo diferente y usar las funciones CGContext (como CGContextScaleCTM o CGContextTranslateCTM o CGContextConcatCTM) y [uiimage drawInRect: Mybounds] ;.

Básicamente tuve que pasar al hilo principal el método renderInContext cuando dibujé la capa en el contexto:

 CGSize sizeView = viewPrintBase.frame.size; UIGraphicsBeginImageContext(sizeView); currentContext = UIGraphicsGetCurrentContext(); dispatch_sync(dispatch_get_main_queue(), ^{ [viewPrintBase.layer renderInContext:currentContext]; [imageViewPhotoUser.layer renderInContext:currentContext]; if (imageViewMask) { [imageViewMask.layer renderInContext:currentContext]; } }); [imageSnapShotDrawinfView drawInRect:viewPrintBase.bounds]; UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); CGImageRef imageRef = CGImageCreateWithImageInRect([finalImage CGImage], viewPrintBase.bounds); // or use the UIImage wherever you like imageSnapShot = [UIImage imageWithCGImage:imageRef]; CGImageRelease(imageRef); 

También tuve que moverme al hilo principal de todos los objetos de la interfaz de usuario, como:

  __block UIView *viewPrintBase; dispatch_sync(dispatch_get_main_queue(), ^{ viewPrintBase = [[UIView alloc]initWithFrame:CGRectMake(0, 0, WIDTH_FINAL_IMAGE, HEIGHT_FINAL_IMAGE)]; viewPrintBase.backgroundColor = [UIColor whiteColor]; [viewPrintBase setClipsToBounds:YES]; //We get the photo user }); 

Espero que esto ayude 🙂

primero compruebe si su aplicación tiene permiso para acceder a la cámara o no. Creo que presionó la opción “no” la primera vez que la cámara se inicia en la aplicación. Ahora haga una cosa. ve a Configuración-> Privacidad-> Cámara y luego elige tu aplicación para comprobar si está activada o desactivada si está activada. Ahora puedes acceder a la cámara en la aplicación.

Parece que este es el problema de iOS 7. Incluso me enfrenté a una situación similar en la que cuando subo la foto desde la galería de imágenes desde mi aplicación, y luego bash abrir la cámara, aparece una pantalla negra.