with uiimagepickercontrollerdelegate open example ios objective-c uiimagepickercontroller ios8 screen-rotation

ios - open - uiimagepickercontrollerdelegate swift 4



La cámara UIImagePickerController gira de manera extraña en iOS 8(fotos) (12)

Aquí hay una solución que encontré al agregar esta categoría a UIImagePickerController :

@implementation UIImagePickerController (Rotation) - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator { [self viewWillAppear:NO]; [self viewDidAppear:NO]; } - (void)viewWillDisappear:(BOOL)animated { [[UIApplication sharedApplication] setStatusBarHidden:NO]; } @end

Me doy cuenta de que es UIViewController llamar directamente a los métodos de ciclo de vida de UIViewController , pero esta es la única solución que he encontrado. ¡Espero que Apple solucione esto pronto!

Tengo una aplicación muy simple: - Todas las orientaciones están permitidas con solo un botón en una pantalla - El botón muestra un UIImagePickerController (para tomar una foto) - Construye con Xcode 5 y SDK 7

En iOS 8 , la cámara del UIImagePickerController aparece correctamente si estoy en el paisaje o en el retrato, pero cuando giro el dispositivo, obtuve la cámara con una rotación de 90 grados, he aquí un ejemplo:

  1. Tengo mi aplicación en el retrato
  2. UIImagePickerController el botón que me muestra el UIImagePickerController
  3. Estoy en la vista de cámara y voy al modo horizontal, esto es lo que obtengo:

La vista está en el paisaje, pero la cámara gira 90 grados

¿Alguien más ya tuvo este problema?

PD: Y si tomo una foto (de nuevo en el paisaje), la foto se toma correctamente y ahora se muestra correctamente:

EDITAR

El error parece estar solucionado en mi iPad que ejecuta iOS 8.1 pero no aparece nada relacionado con ese error en iOS 8.1 Notas de la versión: https://developer.apple.com/library/content/releasenotes/General/RN-iOSSDK-8.1/

¡Gracias a todos por las correcciones propuestas para las versiones anteriores de iOS 8!


Como dijo @hitme, es un error en iOS 8, pero puedes -[UIImagePickerController cameraViewTransform] el problema configurando -[UIImagePickerController cameraViewTransform] antes de presentarlo:

CGFloat angle; switch (interfaceOrientation) { case UIInterfaceOrientationLandscapeLeft: angle = M_PI_2; break; case UIInterfaceOrientationLandscapeRight: angle = -M_PI_2; break; case UIInterfaceOrientationPortraitUpsideDown: angle = M_PI; break; default: angle = 0; break; } imagePicker.cameraViewTransform = CGAffineTransformMakeRotation([UIApplication sharedApplication].statusBarOrientation);


Creo que es un error de iOS 8. Por ejemplo, si abre su aplicación de contactos y hace clic en editar / agregar foto / tomar foto, ¡el mismo problema ocurre en una aplicación estándar de iOS! Publique el problema al soporte de Apple tal como lo hice.


Creo que esto es un error de iOS 8 como lo mencioné. Archivé un Apple Ticket con respecto al ejemplo de la aplicación de contactos e hice una copia de radar abierta aquí http://openradar.appspot.com/18416803

Detalles del informe de error
Resumen: en la aplicación Contactos, si el usuario gira el dispositivo iPad de forma horizontal y coloca el dispositivo sobre un escritorio o lo mantiene nivelado con el suelo, se abrirá el visor de la cámara girado 90 grados con barras negras a los lados. El usuario puede tomar la foto que aparece rotada correctamente. Esta es una experiencia de usuario terrible y hace que el usuario tenga muchas dificultades para capturar una imagen.

Pasos para reproducir:
1. Abra la aplicación Contactos
2. Gire el iPad al modo horizontal
3. Acueste el iPad sobre un escritorio
4. Agregar nuevo contacto
5. Agrega foto> Toma foto 6. Levanta el iPad

Resultados previstos:
Visor de captura de imagen Se visualiza en pantalla completa en modo Paisaje.

Resultados actuales:
El visor de captura de imagen se gira 90 grados y no es pantalla completa.

Versiones afectadas: iOS 8.0, 8.0.2 y 8.1.


El problema se ha solucionado en iOS 8.1 Probado con la aplicación Contactos. funciona bien.

Pero otro problema que encontré,

  1. Ir a la aplicación Contactos
  2. Mantenga su dispositivo como si la cámara ipad estuviera de cara al suelo.
  3. Agregar contacto -> Tomar foto

Pruébelo 2 3 veces con orientación cara arriba, la vista de la cámara comenzará a girar de forma extraña nuevamente como puede ver en las imágenes cargadas arriba.


Encontré un parche fácil y preciso para resolver este problema. Agregue el siguiente código antes de presentar UIImagePickerController:

if (iOS8_Device) { if([[UIDevice currentDevice]orientation] == UIDeviceOrientationFaceUp) { if([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeLeft) { [[UIDevice currentDevice]setValue:[NSNumber numberWithInteger:UIDeviceOrientationLandscapeRight] forKey:@"orientation"]; } else { [[UIDevice currentDevice]setValue:[NSNumber numberWithInteger:UIDeviceOrientationLandscapeLeft] forKey:@"orientation"]; } } }

También necesita subclase UIImagePickerController y anular el siguiente método para trabajarlo mejor.

- (BOOL)shouldAutorotate { [super shouldAutorotate]; return NO; }

Después de usar el código anterior, funcionará bien para la orientación horizontal y la orientación no cambiará al modo UIDeviceOrientationFaceUp.


Este es el código que utilicé para arreglar mi aplicación que estaba rotando la cámara openCV en el paisaje si la cámara se inició con el dispositivo sobre la mesa en posición boca arriba. La cámara debe ser forzada al modo vertical para que la aplicación funcione correctamente.

- (BOOL)shouldAutorotate { [super shouldAutorotate]; return NO; } -(void)viewDidAppear:(BOOL)animated { [super viewDidAppear: animated]; if([[UIDevice currentDevice]orientation] == UIDeviceOrientationFaceUp) { if([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeLeft) { [[UIDevice currentDevice]setValue:[NSNumber numberWithInteger:UIDeviceOrientationPortrait] forKey:@"orientation"]; } else { [[UIDevice currentDevice]setValue:[NSNumber numberWithInteger:UIDeviceOrientationPortrait] forKey:@"orientation"]; } } }


He encontrado otra muy buena solución para este problema que estoy usando actualmente. Solo debe pasar la imagen como un arugument a este método después de capturar la imagen usando UIImagePickerController. Funciona bien para todas las versiones de iOS y también para las orientaciones vertical y horizontal de la cámara. Comprueba la propiedad EXIF ​​de la imagen usando UIImageOrientaiton y de acuerdo con el valor de la orientación, transforma y escala la imagen para que obtenga la misma imagen de retorno con la misma orientación que la orientación de la vista de la cámara.

Aquí he mantenido resoluciones máximas de 3000 para que la calidad de la imagen no se estropee especialmente mientras usa dispositivos Retina, pero puede cambiar su resolución según sus requisitos.

// Código objetivo C:

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info; { UIImage *imagePicked = [info valueForKey:UIImagePickerControllerOriginalImage]; imagePicked = [self scaleAndRotateImage:imagePicked]; [[self delegate] sendImage:imagePicked]; [self.imagePicker dismissViewControllerAnimated:YES completion:nil]; } - (UIImage *) scaleAndRotateImage: (UIImage *)image { int kMaxResolution = 3000; // Or whatever CGImageRef imgRef = image.CGImage; CGFloat width = CGImageGetWidth(imgRef); CGFloat height = CGImageGetHeight(imgRef); CGAffineTransform transform = CGAffineTransformIdentity; CGRect bounds = CGRectMake(0, 0, width, height); if (width > kMaxResolution || height > kMaxResolution) { CGFloat ratio = width/height; if (ratio > 1) { bounds.size.width = kMaxResolution; bounds.size.height = bounds.size.width / ratio; } else { bounds.size.height = kMaxResolution; bounds.size.width = bounds.size.height * ratio; } } CGFloat scaleRatio = bounds.size.width / width; CGSize imageSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef)); CGFloat boundHeight; UIImageOrientation orient = image.imageOrientation; switch(orient) { case UIImageOrientationUp: //EXIF = 1 transform = CGAffineTransformIdentity; break; case UIImageOrientationUpMirrored: //EXIF = 2 transform = CGAffineTransformMakeTranslation(imageSize.width, 0.0); transform = CGAffineTransformScale(transform, -1.0, 1.0); break; case UIImageOrientationDown: //EXIF = 3 transform = CGAffineTransformMakeTranslation(imageSize.width, imageSize.height); transform = CGAffineTransformRotate(transform, M_PI); break; case UIImageOrientationDownMirrored: //EXIF = 4 transform = CGAffineTransformMakeTranslation(0.0, imageSize.height); transform = CGAffineTransformScale(transform, 1.0, -1.0); break; case UIImageOrientationLeftMirrored: //EXIF = 5 boundHeight = bounds.size.height; bounds.size.height = bounds.size.width; bounds.size.width = boundHeight; transform = CGAffineTransformMakeTranslation(imageSize.height, imageSize.width); transform = CGAffineTransformScale(transform, -1.0, 1.0); transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0); break; case UIImageOrientationLeft: //EXIF = 6 boundHeight = bounds.size.height; bounds.size.height = bounds.size.width; bounds.size.width = boundHeight; transform = CGAffineTransformMakeTranslation(0.0, imageSize.width); transform = CGAffineTransformRotate(transform, 3.0 * M_PI / 2.0); break; case UIImageOrientationRightMirrored: //EXIF = 7 boundHeight = bounds.size.height; bounds.size.height = bounds.size.width; bounds.size.width = boundHeight; transform = CGAffineTransformMakeScale(-1.0, 1.0); transform = CGAffineTransformRotate(transform, M_PI / 2.0); break; case UIImageOrientationRight: //EXIF = 8 boundHeight = bounds.size.height; bounds.size.height = bounds.size.width; bounds.size.width = boundHeight; transform = CGAffineTransformMakeTranslation(imageSize.height, 0.0); transform = CGAffineTransformRotate(transform, M_PI / 2.0); break; default: [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"]; } UIGraphicsBeginImageContext(bounds.size); CGContextRef context = UIGraphicsGetCurrentContext(); if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) { CGContextScaleCTM(context, -scaleRatio, scaleRatio); CGContextTranslateCTM(context, -height, 0); } else { CGContextScaleCTM(context, scaleRatio, -scaleRatio); CGContextTranslateCTM(context, 0, -height); } CGContextConcatCTM(context, transform); CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef); UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return imageCopy; }

// Swift 4.0 Código:

func scaleAndRotateImage(image: UIImage, MaxResolution iIntMaxResolution: Int) -> UIImage { let kMaxResolution = iIntMaxResolution let imgRef = image.cgImage! let width: CGFloat = CGFloat(imgRef.width) let height: CGFloat = CGFloat(imgRef.height) var transform = CGAffineTransform.identity var bounds = CGRect.init(x: 0, y: 0, width: width, height: height) if Int(width) > kMaxResolution || Int(height) > kMaxResolution { let ratio: CGFloat = width / height if ratio > 1 { bounds.size.width = CGFloat(kMaxResolution) bounds.size.height = bounds.size.width / ratio } else { bounds.size.height = CGFloat(kMaxResolution) bounds.size.width = bounds.size.height * ratio } } let scaleRatio: CGFloat = bounds.size.width / width let imageSize = CGSize.init(width: CGFloat(imgRef.width), height: CGFloat(imgRef.height)) var boundHeight: CGFloat let orient = image.imageOrientation // The output below is limited by 1 KB. // Please Sign Up (Free!) to remove this limitation. switch orient { case .up: //EXIF = 1 transform = CGAffineTransform.identity case .upMirrored: //EXIF = 2 transform = CGAffineTransform.init(translationX: imageSize.width, y: 0.0) transform = transform.scaledBy(x: -1.0, y: 1.0) case .down: //EXIF = 3 transform = CGAffineTransform.init(translationX: imageSize.width, y: imageSize.height) transform = transform.rotated(by: CGFloat(Double.pi / 2)) case .downMirrored: //EXIF = 4 transform = CGAffineTransform.init(translationX: 0.0, y: imageSize.height) transform = transform.scaledBy(x: 1.0, y: -1.0) case .leftMirrored: //EXIF = 5 boundHeight = bounds.size.height bounds.size.height = bounds.size.width bounds.size.width = boundHeight transform = CGAffineTransform.init(translationX: imageSize.height, y: imageSize.width) transform = transform.scaledBy(x: -1.0, y: 1.0) transform = transform.rotated(by: CGFloat(Double.pi / 2) / 2.0) break default: print("Error in processing image") } UIGraphicsBeginImageContext(bounds.size) let context = UIGraphicsGetCurrentContext() if orient == .right || orient == .left { context?.scaleBy(x: -scaleRatio, y: scaleRatio) context?.translateBy(x: -height, y: 0) } else { context?.scaleBy(x: scaleRatio, y: -scaleRatio) context?.translateBy(x: 0, y: -height) } context?.concatenate(transform) context?.draw(imgRef, in: CGRect.init(x: 0, y: 0, width: width, height: height)) let imageCopy = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return imageCopy! }


No puedo esperar a que Apple solucione el problema ...

- (void)viewWillAppear:(BOOL)animated { ... if (iPad & iOS 8) { switch (device_orientation) { case UIDeviceOrientationPortraitUpsideDown: self.cameraViewTransform = CGAffineTransformMakeRotation(DEGREES_RADIANS(180)); break; case UIDeviceOrientationLandscapeLeft: self.cameraViewTransform = CGAffineTransformMakeRotation(DEGREES_RADIANS(90)); break; case UIDeviceOrientationLandscapeRight: self.cameraViewTransform = CGAffineTransformMakeRotation(DEGREES_RADIANS(-90)); break; default: break; } } }


Sé que es un error de iOS, pero he implementado una solución temporal:

en la vista que presenta el selector de imágenes, agregue este código si no obtiene ningún evento de cambios de orientación (o use didRotateFromInterfaceOrientation otherwhise):

- (void)viewDidLoad { [super viewDidLoad]; // .... if ([[UIDevice currentDevice].systemVersion floatValue] >=8) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didRotate:) name:UIDeviceOrientationDidChangeNotification object:nil]; } }

ahora en rotación, simplemente descarte y represente a su imagepicker:

- (void)didRotate:(NSNotification *)notification { if (self.presentedViewController && self.presentedViewController==self.imagePickerController) { [self dismissViewControllerAnimated:NO completion:^{ [self presentViewController:self.imagePickerController animated:NO completion:nil]; }]; } }

funciona un poco difícil, pero esta es la mejor solución que he encontrado


Tengo el mismo problema. Probé en iOS 7.1.2 e iOS 8. Hasta ahora, solo sucedió en un dispositivo iPad con iOS 8. Por lo tanto, lo soluciono temporalmente siguiendo el siguiente código:

// In my app, I subclass UIImagePickerController and code my own control buttons // showsCameraControls = NO; - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIInterfaceOrientationPortrait] forKey:@"orientation"]; }

No se recomienda porque estropeará la orientación de la presentación de ViewViewController.

¿Ya hay alguna respuesta de Apple?


Tuve el mismo problema y después de volver a lo básico y crear un nuevo proyecto que realmente funcionó ... Lo rastreé hasta;

-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator { // Had forgot to call the following.. [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; }

Espero eso ayude.