Las orientaciones admitidas no tienen una orientación común con la aplicación y, en caso de que Autotate devuelva SÍ '

92

Mi aplicación (iPad; iOS 6) es una aplicación solo horizontal, pero cuando intento usar un UIPopoverController para mostrar la biblioteca de fotos, arroja este error: Supported orientations has no common orientation with the application, and shouldAutorotate is returning YES.Intenté cambiar mucho del código pero no tuve suerte.

Destiny Dawn
fuente
1
deberías aceptar una respuesta. hay mucha gente que pide ayuda y para otras personas que tienen el mismo problema, ¡ayuda cuando marca la respuesta correcta para su problema!
brush51
1
¡No! ninguna solución funciona en iOS 7 :( (headbang)
AsifHabib
La mejor respuesta aquí stackoverflow.com/questions/20468335/…
Damien Romito

Respuestas:

94

En IOS6, ha admitido orientaciones de interfaz en tres lugares:

  1. El .plist (o pantalla de resumen de destino)
  2. Su delegado de solicitud de UIA
  3. El UIViewController que se muestra

Si recibe este error, lo más probable es que la vista que está cargando en su UIPopover solo admita el modo vertical. Esto puede deberse a Game Center, iAd o su propia vista.

Si es su propia vista, puede solucionarlo anulando supportedInterfaceOrientations en su UIViewController:

- (NSUInteger) supportedInterfaceOrientations
{
     //Because your app is only landscape, your view controller for the view in your
     // popover needs to support only landscape
     return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}

Si no es su propia vista (como GameCenter en el iPhone), debe asegurarse de que su .plist admita el modo vertical. También debe asegurarse de que su UIApplicationDelegate admita vistas que se muestran en modo vertical. Puede hacer esto editando su .plist y luego anulando la SupportInterfaceOrientation en su UIApplicationDelegate:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}
Risitas
fuente
3
UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRightes UIInterfaceOrientationMaskAllButUpsideDown UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRightigual a igualUIInterfaceOrientationMaskLandscape
Valerii Pavlov
4
O simplemente use UIInterfaceOrientationMaskAll.
Mark Wang
Perfecto. Aunque una ventana emergente de "solo retrato" funcionará en paisaje, no puede presentar un controlador de vista solo de paisaje de forma modal.
Neal Ehardt
¡No! Solución no funcionó en iOS 7 :(. Stackoverflow.com/questions/23005351/...
AsifHabib
Trabajó en iOS 8. Sin embargo, tuve que agregar soporte vertical para plist. Gracias.
Yaroslav
65

Después de pasar mucho tiempo buscando una forma de evitar subclases y agregar toneladas de código, aquí está mi solución de código de una línea.

Cree una nueva categoría de UIImagePickerController y agregue

-(BOOL)shouldAutorotate{
    return NO;
}

¡Eso es todo amigos!

Dr. Luiji
fuente
1
También funcionó para mí, no lo he probado completamente, pero parece funcionar hasta ahora.
migs647
2
Esta parece ser la mejor solución.
Julián
2
¡Trabajos! Esto es genial, y realmente me ayudó en caso de apuro. Gracias Dr. Luiji !!
brack
1
Agradable. Me funciona en iOS 6. También puede hacer esto configurable en la categoría para una flexibilidad total.
Jared Egan
3
no funciona en iOS7, el método de categoría ni siquiera se llama (aunque está incluido en el pch)
Peter Lapisu
43

Hay otro caso en el que puede aparecer este mensaje de error. Estuve buscando durante horas hasta que encontré el problema. Este hilo fue muy útil después de leerlo un par de veces.

Si su controlador de vista principal se gira a la orientación horizontal e invoca un controlador de vista secundaria personalizado que debe mostrarse en orientación vertical, este mensaje de error puede ocurrir cuando su código se ve así:

- (NSUInteger)supportedInterfaceOrientations {

    return UIInterfaceOrientationPortrait;
}

La trampa aquí fue el intellisense sugerido por xcode "UIInterfaceOrientationPortrait" y no me importó. A primera vista, esto parecía correcto.

La máscara correcta se llama

UIInterfaceOrientationMaskPortrait

Tenga en cuenta el pequeño infijo "Máscara" , de lo contrario su subvista terminará con una excepción y el mensaje de error mencionado anteriormente.

Las nuevas enumeraciones se modifican un poco. ¡Las antiguas enumeraciones devuelven valores inválidos!

(en UIApplication.h puede ver la nueva declaración: UIInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait) )

La solucion es:

- (BOOL)shouldAutorotate {

    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {

    // ATTENTION! Only return orientation MASK values
    // return UIInterfaceOrientationPortrait;

    return UIInterfaceOrientationMaskPortrait;
} 

En uso rápido

override func shouldAutorotate() -> Bool {

    return true
}

override func supportedInterfaceOrientations() -> Int {

    return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}
JackPearse
fuente
5
me pasó por la misma razón
ChenXin
Ojalá Apple hubiera hecho el tipo de retorno UIInterfaceOrientationMask para que sea un poco más obvio lo que se debe devolver.
LightningStryk
La respuesta de Jackpearse parece correcta. Pero cuando mira en el info.plist, hay UISupportedInterfaceOrientations con UIInterfaceOrientationPortrait, UIInterfaceOrientationLandscapeLeft, UIInterfaceOrientationLandscapeRight. No MASK aquí
onmyway133
1
@onmyway: Eso es cierto, los valores de plist no cambiaron. En la versión de iOS anterior, Apple usó los valores de máscara "no" dentro del código. Estas son algunas cosas heredadas. Supongo que Apple está cambiando los valores de plist internamente ahora.
JackPearse
Mi aplicación solía funcionar sin este problema de bloqueo en un simulador de iPad de Xcode 6.2. Y se bloqueó después de que actualicé a Xcode 6.3 hace unos días. Ahora esta solución soluciona mi problema. Muchas gracias :-)
Golden Thumb
22

Tuve un problema similar al presentar el selector de imágenes en una aplicación solo horizontal. Como sugirió el Dr. Luiji, agregué la siguiente categoría al comienzo de mi controlador.

// This category (i.e. class extension) is a workaround to get the
// Image PickerController to appear in landscape mode.
@interface UIImagePickerController(Nonrotating)
- (BOOL)shouldAutorotate;
@end

@implementation UIImagePickerController(Nonrotating)

- (BOOL)shouldAutorotate {
  return NO;
}
@end

Es más fácil agregar estas líneas justo antes de la @implementación de su archivo ViewController .m.

Trausti Kristjansson
fuente
¡Tengo una aplicación solo para retratos! y quiero mostrar la cámara en modo horizontal. ¿¿¿¿¿alguna solución?????
AsifHabib
¿Trausti no funcionó? Tengo el mismo problema y probé su código pero todavía aparece la misma excepción *** Finalizando la aplicación debido a una excepción no detectada 'UIApplicationInvalidInterfaceOrientation', motivo: 'Las orientaciones compatibles no tienen una orientación común con la aplicación, y shouldAutorotate está devolviendo SÍ ..... ... también puse un punto de interrupción en el método de categoría UIimagePickerView shouldAutorotate llegar allí y devuelve no, pero aún así dar esta excepción ... Mi aplicación es solo una aplicación de paisaje ... por favor ayúdame
Vishal16
También funciona para obligar a SKStoreProductViewController a presentarse en vertical cuando toda la aplicación es horizontal en iOS 8. Gracias.
Yaroslav
11

Encontré el mismo mensaje de error en mi código. Encontré esto, es un error según lo informado por Apple:

https://devforums.apple.com/message/731764#731764

Su solución es arreglarlo en AppDelegate. ¡Lo implementé y me funciona!

Robby
fuente
Por cierto, originalmente encontré esto en: stackoverflow.com/questions/12522491/…
Robby
Esta fue la respuesta correcta, directamente de Apple, y luego tuve que seguir las mismas instrucciones pero hacerlo en Swift para una aplicación dirigida a iOS 8. Todo funciona muy bien. AppDelegate establece supportedInterfaceOrientationsForWindow en Horizontal y Portrait, cada archivo rápido individual establece anular func supportedInterfaceOrientations a Horizontal solo para que la vista no gire, pero cuando una vista vertical (en mi caso SKStoreProductViewController) necesita cargarse, ¡funciona!
RanLearns
Por Dios, hay tantas soluciones sugeridas, y esta de lejos no tiene los puntos más altos, pero de hecho es la correcta. Probado en iOS 10 y 9. Nada más funciona.
Demian Turner
6

Tuve el mismo problema y esta respuesta https://stackoverflow.com/a/12523916 funciona para mí. Me pregunto si hay una solución más elegante.

Mi código:

UIImagePickerController  *imagePickerController = [[NonRotatingUIImagePickerController alloc] init];
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

UIPopoverController  *popoverVC = [[UIPopoverController alloc] initWithContentViewController:imagePickerController];    

[popoverVC presentPopoverFromRect:frame   // did you forget to call this method?
                           inView:view
         permittedArrowDirections:UIPopoverArrowDirectionAny
                         animated:YES];
poetowen
fuente
Intenté hacer eso, pero cuando hago clic en el botón para llamar al código, pero no se muestra nada, también intenté agregar @interface NonRotatingUIImagePickerController : UIImagePickerController @end @implementation NonRotatingUIImagePickerController - (BOOL)shouldAutorotate { return NO; } @endal código, pero mi código no detectaba NonRotatingUIImagePickerController.
Destiny Dawn
1
No importa, ahora detecta NonRotatingUIImagePickerController, pero aún no se muestra nada ... @poetowen
Destiny Dawn
4

iOS 8: puede usar UIModalPresentationPopover sin ningún truco para mostrar en una ventana emergente. No es ideal, pero es mejor que nada.

imagePicker.modalPresentationStyle = UIModalPresentationPopover;
imagePicker.popoverPresentationController.sourceView = self.view;
imagePicker.popoverPresentationController.sourceRect = ((UIButton *)sender).frame;

Editar: tal vez pruebe los diferentes UIModalPresentationStyles; tal vez más funcionen en el paisaje.

derbs
fuente
3
- (BOOL)shouldAutorotate {
    return NO;
}

-(NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

This removes the crash.
Suhail Bhat
fuente
2

Otra opción que resolvió mis problemas fue crear una subclase de UIImagePickerController y anular el método siguiente

@interface MyImagePickerController ()

@end

@implementation MyImagePickerController

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
}

Use esto en lugar del UIImagePickerController y todo funciona bien.

Tecnología EquiAvia
fuente
1

Crear una categoría es realmente útil para corregir este error. Y no olvide importar su categoría creada. Esto agregará el método que falta a UIImagePickerController y en iOS 6 lo restringirá para que funcione en Portrait solo como dice la documentación por cierto.

Las otras soluciones pueden haber funcionado. Pero con SDK para iOS 8.x compilado para implementar en iOS 6.1, este parece el camino a seguir.

El archivo .h:

#import <UIKit/UIKit.h>

@interface UIImagePickerController (iOS6FIX)

- (BOOL) shouldAutorotate;
- (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation;

@end

El archivo .m:

#import "UIImagePickerController+iOS6FIX.h"

@implementation UIImagePickerController (iOS6FIX)

- (BOOL) shouldAutorotate {
    return NO;
}

- (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationPortrait;
}

@end
Helge Staedtler
fuente
1

Swift 3

let imagePicker = UIImagePickerController()

imagePicker.modalPresentationStyle = .popover
imagePicker.popoverPresentationController?.sourceView = sender // you can also pass any view 

present(imagePicker, animated: true)
zombi
fuente
0

Me encontré con este problema accidente cuando la conversión UIInterfaceOrientationPortraitde UIInterfaceOrientationMaskPortraitforma implícita como valor de retorno.

Más antecedentes de código UIPageViewControllerDelegate, solo para su información para todos ustedes.

 -(UIInterfaceOrientationMask)pageViewControllerSupportedInterfaceOrientations:
(UIPageViewController *)pageViewController
{
    # return UIInterfaceOrientationPortrait;    # wrong
    return UIInterfaceOrientationMaskPortrait;  # correct
}
Itachi
fuente
0

Acabo de resolver el problema de Swift 4.x

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    configureVideoOrientation()
}

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)
    coordinator.animate(alongsideTransition: nil, completion: { [weak self] _ in
        self?.configureVideoOrientation()
    })
}

private func configureVideoOrientation() {
    guard let previewLayer = self.previewLayer, let connection = previewLayer.connection else { return }
    if connection.isVideoOrientationSupported {
        let orientation = UIApplication.shared.statusBarOrientation
        switch (orientation) {
        case .portrait:
            previewLayer.connection?.videoOrientation = .portrait
        case .landscapeRight:
            previewLayer.connection?.videoOrientation = .landscapeRight
        case .landscapeLeft:
            previewLayer.connection?.videoOrientation = .landscapeLeft
        case .portraitUpsideDown:
            previewLayer.connection?.videoOrientation = .portraitUpsideDown
        default:
            previewLayer.connection?.videoOrientation = .portrait
        }

        previewLayer.frame = self.view.bounds
    }
}

Gracias chicos también por sus respuestas. Acabo de cortar el código trabajado y simplemente lo refactoricé.

atereshkov
fuente
0

Swift 4 en adelante, asumiendo que toda la aplicación está en horizontal y necesita presentar un solo controlador en vertical. En el controlador de vista que debe ser vertical agregue lo siguiente:

override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return .portrait
}

open override var shouldAutorotate: Bool {
    return false
}
Gal en blanco
fuente