Estoy trabajando en una aplicación para iPad, utilizando el diseño Automático, donde si el usuario permite que un determinado modo («heads-up»), quiero apoyar a sólo retrato (retrato o al revés) de la orientación, y además, si el dispositivo está en el paisaje, que me gustaría que cambie automáticamente al modo de retrato.

En la parte superior de la vista controlador, tengo lo siguiente:

- (NSUInteger) supportedInterfaceOrientations {
    if (self.modeHeadsUp) {
        return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
    } else {
        return UIInterfaceOrientationMaskAll;
    }
}

- (BOOL) shouldAutorotate {
    return TRUE;
}

Basado en las respuestas que he visto en otros lugares aquí, la respuesta parece ser que yo debería usar la aplicación «setStatusBarOrientation». Por lo tanto, en el método en el que el usuario ha seleccionado «heads-up», he incluido:

    UIApplication *application = [UIApplication sharedApplication];
    [application setStatusBarOrientation:UIInterfaceOrientationPortrait
                                animated:YES];

Sin embargo, esto simplemente no parece hacer nada. Mientras yo pueda mover físicamente el dispositivo para llegar a girar en vertical, no lo hace automáticamente.

De hecho, cuando en el modo de paisaje después de ejecutar el código anterior para intentar establecer mediante programación la orientación, cuando me consulta de la aplicación «statusBarOrientation» con el siguiente código, se queda en el «4» por el paisaje:

UIApplication *application = [UIApplication sharedApplication];
int orientation = [application statusBarOrientation];
self.movesTextView.text = [NSString stringWithFormat:@"ORIENTATION %d", orientation];

Parecía que tal vez el diseño automático no se activa con el setStatusBarOrientation, así que traté de añadir este código después, a ningún efecto:

    [super updateViewConstraints];
    [self.view updateConstraints];

Me doy cuenta de que Apple quiere salir de la orientación del dispositivo en las manos del usuario. Sin embargo, me gustaría ser capaz de soportar el modo horizontal cuando no en el «heads-up».

Que me estoy perdiendo algo que se pueda forzar el cambio de orientación?

InformationsquelleAutor John Stewart | 2014-01-08

17 Comentarios

  1. 190

    Para iOS 7 & 8:

    Objective-C:

    NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
    [[UIDevice currentDevice] setValue:value forKey:@"orientation"];

    Swift 3+:

    let value = UIInterfaceOrientation.landscapeLeft.rawValue
    UIDevice.current.setValue(value, forKey: "orientation")

    Yo lo llamo en - viewDidAppear:.

    • Esto funciona! Ahora, me preocupa que esto genera un compilador de error, y la gente parece ceño poderosamente sobre objc_msgSend (ver stackoverflow.com/questions/17263354/…), pero esto funciona! Voy a probar y ver si hay una manera de hacer esto de una manera más limpia.
    • Por desgracia, este parece ser un final de carrera alrededor de la ahora obsoleta (y no está disponible en iOS7) «[UIDevice currentDevice] setOrientation». Mientras que no de trabajo, tengo una sensación de que esto es algo que ha sido rechazada por Apple, de lo contrario me iba a marcar esto como una respuesta correcta.
    • Cuando yo intente esto SÓLO funciona en el iPad. Tanto el iPad Mini (iOS 7.1) y el iPhone 5s (iOS 7.1) no funcionan. El simulador para todos los dispositivos funciona
    • Asegúrese de Que ha establecido todos los modo de orientación para su aplicación,
    • no hay ningún problema con este método. he utilizado en varias aplicaciones cada vez que es aceptada por apple
    • GRACIAS
    • No funciona en el iPad Aire sea. Extraño. Yo tenía esta solución exacta y era una prueba de ayer por la noche en un iPad 3, hoy en el trabajo, el código sólo no gira.
    • ¿appple acepta apps con este método?
    • No estoy seguro, Pero he utilizado en muchos proyectos de apple aún no ha rechazado..
    • mi aplicación también se aprobó por parte de apple. Así que no habrá ningún problema con esto.Pero esto no funciona para iPhone 5s (iOS 7.1).
    • Es allí cualquier manera de conseguir que esto funcione, sin la animación?
    • Este es el oro, especialmente cuando se utiliza UIViewController.attemptRotationToDeviceOrientation() y stackoverflow.com/questions/24928057/… usted puede obtener en cualquier vista de instalación que desea!
    • Muchas gracias @SidShah ! Debe ser aceptado respuesta !
    • si no funciona en algunos dispositivos, probablemente el dispositivo tiene BLOQUEO de ORIENTACIÓN en la configuración de usuario!
    • el código de trabajo en el iPad ios9!
    • Wow muchas gracias
    • las actualizaciones para IOS 11?
    • Acabo de dos accidentes ocurridos durante la prueba, utilizando este método. ¿Alguien sabe de otra forma?
    • Como algunos otros han mencionado. Cuando la configuración de la orientación del dispositivo de forma manual, el método de delegado para las orientaciones no siempre se llama, por lo que esta solución funciona de manera intermitente. Si usted sigue este código con una llamada a UIViewController.attemptRotationToDeviceOrientation(), entonces se llama siempre para mí. Esto puede ser un nuevo requisito, ya que este fue contestado, puede que desee revisar añadir este detalle.

  2. 20

    Uso de este. La solución perfecta para la orientación problema..ios7 y anteriores

    [[UIDevice currentDevice] setValue:
        [NSNumber numberWithInteger: UIInterfaceOrientationPortrait]
            forKey:@"orientation"];
    • Esto funciona para mí. Pero es esta aceptado por apple?
    • Sí amigo.Es aceptado por apple.
    • Funciona incluso en iOS 8. Perfecto.
    • Esto es aceptado por Apple de la aplicación de revisión de equipo (por ahora), pero yo no diría que es «aceptado por Apple». Es decir, es un hack para el uso de clave-valor de codificación y puede dejar de funcionar en cualquier futura versión de iOS.
    • Donde debería añadir este código, he añadido en viewwillapear pero no funciona, por favor explique.
    • ¿has probado en viewDidLoad ?
    • He probado con todo, didload, willapear, didapear. Uno de mis proyectos está atascado en ios8 debido a la Orientación de la cuestión. quiero que todos los de la vista en el retrato sino un punto de vista(reproductor de vídeo) con el modo de paisaje, he comprobado retrato y a la izquierda modo de paisaje en el guión gráfico. Yo hv intentado todo el código pero no funciona, creo que me falta algo. Por favor, consejos y si tienes Demo por favor hare.
    • Rysanek:he probado con todo, didload, willapear, didapear. Uno de mis proyectos está atascado en IOS 8 debido a la Orientación de la cuestión. quiero que todos los de la vista en el retrato sino un punto de vista(reproductor de vídeo) con el modo de paisaje, he comprobado retrato y a la izquierda modo de paisaje en el guión gráfico. Yo hv intentado todo el código pero no funciona, creo que me falta algo. Por favor, consejos y si tienes Demo por favor hare.
    • ¿Cómo puedo saber si este método ya ha terminado de ejecutar?
    • esto es realmente grande. todavía funciona en iOS 9.3.2.
    • Versión comprimida: [[UIDevice currentDevice] setValue:@(UIInterfaceOrientationLandscapeLeft) forKey:@»orientación»];
    • cómo hacer un restablecimiento de la orientación a todos los valores, tanto en el paisaje y el retrato ?

  3. 10

    Usted necesita llamar a attemptRotationToDeviceOrientation (UIViewController) para hacer que el sistema llame a su supportedInterfaceOrientations cuando la condición ha cambiado.

    • En mi código, he tratado de sustituir la aplicación setStatusBarOrientation método con [UIViewController attemptRotationToDeviceOrientation], como lo sugieren. Sin embargo, parece no tener ningún efecto, por desgracia.
    • Me parece que este hilo también que, mientras sus sugerencias parece ser la «respuesta correcta», simplemente no funciona: stackoverflow.com/questions/19125263/…
    • esto sólo funciona si la orientación del dispositivo es diferente UIViewController‘s de orientación
  4. 5
    NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft]; [[UIDevice currentDevice] setValue:value forKey:@"orientation"];

    hace el trabajo, pero usted tiene que devolver shouldAutorotate con SÍ en su controlador de vista de

    - (BOOL)shouldAutorotate
    {
        return self.shouldAutoRotate;
    }

    Pero si usted lo hace, su VC rotación automática si el usuario gira el dispositivo…
    así que he cambiado a:

    @property (nonatomic, assign) BOOL shouldAutoRotate;
    
    - (BOOL)shouldAutorotate
    {
        return self.shouldAutoRotate;
    }

    y me llame

    - (void)swithInterfaceOrientation:(UIInterfaceOrientation)orientation
    {
        self.rootVC.shouldAutoRotate = YES;
    
        NSNumber *value = [NSNumber numberWithInt: orientation];
        [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
    }

    para forzar una nueva orientación con un clic de botón.
    Para establecer la espalda shouldAutoRotate a NO, he añadido a mi rootVC

    - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
    {
        self.shouldAutoRotate = NO;
    }

    PS: Esta solución no funciona en todos los simuladores demasiado.

    • Divertido.. yo estaba buscando algo así y ¿qué encontré? La única solución para iOS 11 y la escribí yo 1,5 años.. Y me di cuenta de que cuando me quise dar un +1 para la solución 😀
    • wow… señor te mereces un upvote, este es por lejos la solución más limpia que he visto
  5. 4

    Esto funciona para mí en Xcode 6 & 5.

    - (BOOL)shouldAutorotate {
        return YES;
    }
    - (NSUInteger)supportedInterfaceOrientations {
        return (UIInterfaceOrientationMaskPortrait);
    }
    • Muchas gracias, es que a mi me funciona en iOS 8, XCode 6
  6. 3

    La única forma en que ha funcionado para mí es la presentación de maniquí modal de controlador de vista.

    UIViewController* dummyVC = [[UIViewController alloc] init];
    dummyVC.view = [[UIView alloc] init];
    [self presentModalViewController:dummyVC animated:NO];
    [self dismissModalViewControllerAnimated:NO];

    El VC se solicitará la actualización de la interfaz de orientaciones cuando modal de controlador de vista es despedido.

    Cosa curiosa es que UINavigationController hace exactamente esto cuando se empuja/popping niño con controladores de interfaz compatible con diferentes orientaciones (probado en iOS 6.1, 7.0).

    • Como se ha mencionado en otros lugares, esto ya no funciona en iOS 8.
  7. 3

    Si usted tiene un UIViewController que deben permanecer en el modo de Retrato, sólo tiene que añadir esta reemplazar y listo.

    override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        return UIInterfaceOrientationMask.Portrait
    }

    La mejor parte es que no hay animación cuando este punto de vista se muestra, es sólo ya en la orientación correcta.

  8. 3

    Esta solución permite forzar una determinada interfaz de orientación, con carácter temporal, sobrescribiendo el valor de UIDevice.current.orientation y luego pedir al sistema para girar la interfaz para que coincida con el dispositivo de rotación:

    Importante: Este es un hack, y podría dejar de funcionar en cualquier momento

    Agregar lo siguiente en su aplicación raíz del controlador de vista:

    class RootViewController : UIViewController {
    private var _interfaceOrientation: UIInterfaceOrientation = .portrait
    override var supportedInterfaceOrientations: UIInterfaceOrientationMask { return UIInterfaceOrientationMask(from: _interfaceOrientation) }
    override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation { return _interfaceOrientation }
    override func viewDidLoad() {
    super.viewDidLoad()
    //Register for notifications
    NotificationCenter.default.addObserver(self, selector: #selector(RootViewController.handleInterfaceOrientationChangeRequestedNotification(_:)), name: .interfaceOrientationChangeRequested, object: nil)
    }
    deinit { NotificationCenter.default.removeObserver(self) }
    func handleInterfaceOrientationChangeRequestedNotification(_ notification: Notification) {
    guard let interfaceOrientation = notification.object as? UIInterfaceOrientation else { return }
    _interfaceOrientation = interfaceOrientation
    //Set device orientation
    //Important:
    //• Passing a UIDeviceOrientation here doesn't work, but passing a UIInterfaceOrientation does
    //• This is a hack, and could stop working at any moment
    UIDevice.current.setValue(interfaceOrientation.rawValue, forKey: "orientation")
    //Rotate the interface to the device orientation we just set
    UIViewController.attemptRotationToDeviceOrientation()
    }
    }
    private extension UIInterfaceOrientationMask {
    init(from interfaceOrientation: UIInterfaceOrientation) {
    switch interfaceOrientation {
    case .portrait: self = .portrait
    case .landscapeLeft: self = .landscapeLeft
    case .landscapeRight: self = .landscapeRight
    case .portraitUpsideDown: self = .portraitUpsideDown
    case .unknown: self = .portrait
    }
    }
    }
    extension Notification.Name {
    static let interfaceOrientationChangeRequested = Notification.Name(rawValue: "interfaceOrientationChangeRequested")
    }

    Asegúrese de que todos los de la interfaz de orientaciones son verificados bajo de Implementación «Info»:

    ¿Cómo puedo establecer mediante programación de la orientación del dispositivo en iOS 7?

    Solicitud de la interfaz de los cambios de orientación de donde usted los necesita:

    NotificationCenter.default.post(name: .interfaceOrientationChangeRequested, object: UIInterfaceOrientation.landscapeRight)
  9. 2

    Si desea bloquear la vista principal de la aplicación para retrato, pero desea abrir popup puntos de vista en el paisaje, y usted está utilizando tabBarController como rootViewController como soy, usted puede utilizar este código en tu AppDelegate.

    AppDelegate.h

    @interface AppDelegate : UIResponder <UIApplicationDelegate, UITabBarControllerDelegate>
    @property (strong, nonatomic) UIWindow *window;
    @property (strong, nonatomic) UITabBarController *tabBarController;
    @end

    AppDelegate.m

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    //Create a tab bar and set it as root view for the application
    self.tabBarController = [[UITabBarController alloc] init];
    self.tabBarController.delegate = self;
    self.window.rootViewController = self.tabBarController;
    ...
    }
    - (NSUInteger)tabBarControllerSupportedInterfaceOrientations:(UITabBarController *)tabBarController
    {
    return UIInterfaceOrientationMaskPortrait;
    }
    - (UIInterfaceOrientation)tabBarControllerPreferredInterfaceOrientationForPresentation:(UITabBarController *)tabBarController
    {
    return UIInterfaceOrientationPortrait;
    }

    Funciona muy bien.

    En su viewController desea ser presentado en el paisaje, sólo tiene que utilizar la siguiente:

    - (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
    }
    - (BOOL)shouldAutorotate {
    return YES;
    }
    • Interesante. Voy a jugar con esto cuando tengo mi app de reestructuración. Actualmente no hay ningún contenedor controlador de vista, pero he estado con la intención de envolver en uno de todos modos. Gracias.
    • No me funciona
    • Para mí el último bloque de código funcionó bien! Pero yo también no tienen ninguna UINavigationController o UITabBarController integrado, de forma tal vez un poco de diferencia de otra manera.
  10. 2
    1. Añadir esta declaración en AppDelegate.h

      //whether to allow cross screen marker 
      @property (nonatomic, assign) allowRotation BOOL;
    2. Escribir esta sección de código en AppDelegate.m

      - (UIInterfaceOrientationMask) application: (UIApplication *) supportedInterfaceOrientationsForWindow: application (UIWindow *) window {
      If (self.allowRotation) {
      UIInterfaceOrientationMaskAll return;
      }
      UIInterfaceOrientationMaskPortrait return;
      }
    3. Cambiar el allowRotation propiedad de delegado de la aplicación

    • Bienvenido a StackOverflow. Podría por favor dar formato al código un poco mejor para que sea más legible?
  11. 1

    La base UINavigationController debe tener la siguiente devolución de llamada para que el niño los elementos puede decidir cuál es la orientación que desee.

    -(NSUInteger)supportedInterfaceOrientations {
    UIViewController *topVC = self.topViewController;
    return topVC.supportedInterfaceOrientations;
    }
    -(BOOL)shouldAutorotate {
    UIViewController *topVC = self.topViewController;
    return [topVC shouldAutorotate];
    }
  12. 1

    Si quieres sólo el modo de retrato, en iOS 9 (Xcode 7) usted puede:

    • Va a Info.plist
    • Seleccione «interfaz Compatible con las orientaciones de» elemento
    • Eliminar «Paisaje(a la izquierda del botón home)» y «Paisaje(a la derecha del botón home)»

    ¿Cómo puedo establecer mediante programación de la orientación del dispositivo en iOS 7?

  13. 1

    Yo estaba en un problema similar que usted. Necesito dispositivo de bloqueo de la orientación de algunas pantallas (como la de inicio de Sesión) y permitir la rotación en los demás.

    Después de un par de cambios y siguiendo algunas respuestas yo lo hice por:

    • La habilitación de todas las orientaciones en la Información del Proyecto.plist.

    ¿Cómo puedo establecer mediante programación de la orientación del dispositivo en iOS 7?

    • Desactivación de orientación en los ViewControllers donde me necesite el dispositivo no para de girar, como en la pantalla de inicio de Sesión en mi caso. Necesitaba reemplazar shouldAutorotate método de la VC:

    -(BOOL)shouldAutorotate{
    return NO;
    }

    La esperanza de que esto funcionará para usted.

  14. 1

    aquí se trata de un ejemplo de TRABAJO para iOS 7, 8, 9, 10 cómo cambiar la aplicación de la orientación a su actual opuesto

    Objective-C

    - (void)flipOrientation
    {
    NSNumber *value;
    UIInterfaceOrientation currentOrientation = [[UIApplication sharedApplication] statusBarOrientation];
    if(UIInterfaceOrientationIsPortrait(currentOrientation))
    {
    if(currentOrientation == UIInterfaceOrientationPortrait)
    {
    value = [NSNumber numberWithInt:UIInterfaceOrientationPortraitUpsideDown];
    }
    else //if(currentOrientation == UIInterfaceOrientationPortraitUpsideDown)
    {
    value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
    }
    }
    else
    {
    if(currentOrientation == UIInterfaceOrientationLandscapeRight)
    {
    value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
    }
    else //if(currentOrientation == UIInterfaceOrientationLandscapeLeft)
    {
    value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
    }
    }
    [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
    [UIViewController attemptRotationToDeviceOrientation];
    }

    Swift 3

    func flipOrientation() -> Void
    {
    let currentOrientation : UIInterfaceOrientation = UIApplication.shared.statusBarOrientation
    var value : Int = 0;
    if(UIInterfaceOrientationIsPortrait(currentOrientation))
    {
    if(currentOrientation == UIInterfaceOrientation.portrait)
    {
    value = UIInterfaceOrientation.portraitUpsideDown.rawValue
    }
    else //if(currentOrientation == UIInterfaceOrientation.portraitUpsideDown)
    {
    value = UIInterfaceOrientation.portrait.rawValue
    }
    }
    else
    {
    if(currentOrientation == UIInterfaceOrientation.landscapeRight)
    {
    value = UIInterfaceOrientation.landscapeLeft.rawValue
    }
    else //if(currentOrientation == UIInterfaceOrientation.landscapeLeft)
    {
    value = UIInterfaceOrientation.landscapeRight.rawValue
    }
    }
    UIDevice.current.setValue(value, forKey: "orientation")
    UIViewController.attemptRotationToDeviceOrientation()
    }
    • Siento poner raw cadena "orientation" no es bueno.
    • esta solución utiliza la reflexión técnica, como iOS no tiene / mostrar cualquier método público para lograr este objetivo, por lo que tenemos que hacer es vie reflexión
    • Así, en última instancia, estamos modificando las cosas que Apple no quiere de nosotros: UIDevice‘s orientation propiedad está lista sólo. Ha enfrentado el rechazo de la aplicación de este código nunca?
    • lo siento, pero no puedo responder, ya que la aplicación en la que el usuario este trozo de código es lanzado fuera de iTunes, intenta presentar algunas código como este?
    • Nope, nunca con este código.
  15. 0

    Probar esto, junto con su código.

    -(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation  
    -(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration

    una vez que el usuario seleccione cualquier opción, a continuación, llamar a este método, puesto que el usuario puede estar en el modo de paisaje y, a continuación, se puede establecer sólo el modo de retrato en el mismo controlador de vista por lo que automáticamente la vista debe ser trasladado a modo de retrato así que en ese botón acton llamar a este

    -(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
    • No estoy muy seguro de lo que estás sugiriendo, pero shouldAutorotateToInterfaceOrientation parece estar en desuso en iOS7 en favor de shouldAutorotate, que me han puesto en práctica.
    • lo siento, mi error. uso shouldAutorotate sólo y -(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duración:(NSTimeInterval)duración
    • He añadido [self willRotateToInterfaceOrientation:UIInterfaceOrientationPortrait duration:ROTATE_VIEW_DELAY]; para el método en donde el heads-up está seleccionado el modo, la sustitución de Sunny Shah objc_msgSend respuesta anterior. Por desgracia, todavía no hay efecto en la pantalla. Es mi entendimiento de que «willrotate» es llamada cuando la pantalla está a punto de girar, en respuesta a que el usuario mover físicamente el dispositivo.
    • Stewart le puede llamar a este método de forma independiente… Pero dime ¿qué es el código que escribió en este método. Si es posible puedes actualizar tu pregunta con todo el código escrito para la orientación (todos los métodos que se utilizan)
    • Charan Giri – he creado un sencillo proyecto de prueba para demostrar: github.com/johnstewart/RotateTest. El proyecto es una sencilla aplicación para iPad con un ImageView, y un interruptor para el encendido de «retrato» sólo de encendido y apagado. Empecé con una vista en blanco-solo proyecto, y se añade a esta propiedad: @property (nonatomic) bool modePortraitOnly;
    • - (NSUInteger) supportedInterfaceOrientations { if (self.modePortraitOnly) { return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown; } else { return UIInterfaceOrientationMaskAll; } } y cuando el control de cambios, yo simplemente hacer ` [auto willRotateToInterfaceOrientation:UIInterfaceOrientationPortrait duración:1.0]; ` pero como usted puede ver si usted lo intente, no hace nada. Comentario esta línea y agregar Soleado del sha de arriba y haga el trabajo.
    • Para probar, ejecutar la aplicación. Desmarque la casilla. Girar a horizontal. Casilla de verificación. Verás que la orientación no cambia.

  16. 0

    Esto funcionó a mí perfectamente….

    NSNumber *value = [NSNumber numberWithInt:UIDeviceOrientationPortrait];
    [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
  17. 0

    Para aquellos como yo que lucharon para conseguir @Soleado Shah aceptado responder a trabajar en el ipad. Usted necesidad de establecer la «Requiere pantalla completa» casilla de verificación en la configuración del proyecto. Tenga en cuenta que esto evitará que su aplicación a partir de trabajar en modo multitarea que puede o no ser aceptable.

    ¿Cómo puedo establecer mediante programación de la orientación del dispositivo en iOS 7?

Dejar respuesta

Please enter your comment!
Please enter your name here