Cómo bloquear la orientación de un controlador de vista en modo vertical solo en Swift

95

Dado que mi aplicación tiene soporte para todas las orientaciones. Me gustaría bloquear solo el modo vertical en un UIViewController específico.

por ejemplo, supongamos que se trataba de una aplicación con pestañas y cuando la vista de inicio de sesión aparece de forma modal, solo quiero que la vista de inicio de sesión esté en el modo vertical sin importar cómo el usuario gire el dispositivo o cómo será la orientación actual del dispositivo

Thiha Aung
fuente
Esto puede ayudar a stackoverflow.com/q/24928057/6521116
Kris Roofe

Respuestas:

262

Las cosas pueden complicarse bastante cuando tiene una jerarquía de vista complicada, como tener varios controladores de navegación y / o controladores de vista de pestañas.

Esta implementación permite que los controladores de vista individuales establezcan cuándo les gustaría bloquear las orientaciones, en lugar de depender del Delegado de la aplicación para encontrarlas iterando a través de subvistas.

Rápido 3, 4, 5

En AppDelegate:

/// set orientations you want to be allowed in this property by default
var orientationLock = UIInterfaceOrientationMask.all

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        return self.orientationLock
}

En alguna otra estructura global o clase auxiliar, aquí creé AppUtility:

struct AppUtility {

    static func lockOrientation(_ orientation: UIInterfaceOrientationMask) {
    
        if let delegate = UIApplication.shared.delegate as? AppDelegate {
            delegate.orientationLock = orientation
        }
    }

    /// OPTIONAL Added method to adjust lock and rotate to the desired orientation
    static func lockOrientation(_ orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation:UIInterfaceOrientation) {
   
        self.lockOrientation(orientation)
    
        UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")
        UINavigationController.attemptRotationToDeviceOrientation()
    }

}

Luego, en el ViewController deseado, desea bloquear las orientaciones:

 override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    
    AppUtility.lockOrientation(.portrait)
    // Or to rotate and lock
    // AppUtility.lockOrientation(.portrait, andRotateTo: .portrait)
    
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    
    // Don't forget to reset when view is being removed
    AppUtility.lockOrientation(.all)
}

Si iPad o aplicación universal

Asegúrese de que "Requiere pantalla completa" esté marcado en Configuración de destino -> General -> Información de implementación. supportedInterfaceOrientationsForno se llamará al delegado si no está marcado. ingrese la descripción de la imagen aquí

bmjohns
fuente
Parece que es control de código ... déjame comprobarlo, parece una buena respuesta.
Thiha Aung
17
Después de mucha investigación locamente, esta es la única respuesta que encontré que funciona para mí. Swift 3 - Xcode 8.2.1
Xavier García Rubio
1
@pbm Varias de las aplicaciones de la empresa en las que trabajo con orientaciones de bloqueo en partes específicas de la aplicación, y todas han sido aprobadas para la tienda de aplicaciones varias veces, durante muchos años. Dicho esto, sin embargo, no puedo garantizar que Apple no tendrá problemas con esto en el futuro. Pero hasta ahora no hay problemas, y estoy bastante seguro de que muchas aplicaciones lo hacen de una forma u otra.
bmjohns
2
Si lo marca Requires full screen, evitará que la aplicación esté disponible para Slide Over y Split View. Consulte Adopción de mejoras multitarea en iPad de Apple. Tengo una respuesta que no requiere habilitarRequires full screen
John Pang
2
No funciona, el diseño de la segunda vista del controlador no actualizó su visualización solo en vertical.
The iCoder
27

Rápido 4

ingrese la descripción de la imagen aquí AppDelegate

var orientationLock = UIInterfaceOrientationMask.all

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
    return self.orientationLock
}
struct AppUtility {
    static func lockOrientation(_ orientation: UIInterfaceOrientationMask) {
        if let delegate = UIApplication.shared.delegate as? AppDelegate {
            delegate.orientationLock = orientation
        }
    }

    static func lockOrientation(_ orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation:UIInterfaceOrientation) {
        self.lockOrientation(orientation)
        UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")
    }
}

Su ViewController agregue la siguiente línea si solo necesita orientación vertical. tienes que aplicar esto a todas las necesidades de ViewController para mostrar el modo vertical.

override func viewWillAppear(_ animated: Bool) {
AppDelegate.AppUtility.lockOrientation(UIInterfaceOrientationMask.portrait, andRotateTo: UIInterfaceOrientation.portrait)
    }

y eso hará que la orientación de la pantalla para otros Viewcontroller sea de acuerdo con la orientación física del dispositivo.

override func viewWillDisappear(_ animated: Bool) {
        AppDelegate.AppUtility.lockOrientation(UIInterfaceOrientationMask.all)

    }
Nahid Raihan
fuente
Para Swift 4, esta es definitivamente la mejor respuesta. Es exactamente lo que necesitaba, ya que imita el comportamiento de la aplicación de la cámara de iOS.
nocdib
@Nahid ¿Reemplazamos el func application delegado original dentro de la aplicación con esta función?func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { return self.orientationLock ?
Moondra
Después de una o dos horas de buscar una solución y algunos intentos, esta es la solución que funciona perfectamente. Establece la orientación de la vista, la fuerza cuando se carga la vista, se desbloquea cuando se va a otra vista, funciona en la navegación de pestañas y el código es simple y limpio. Gracias @Nahid
Radek Sip
12

Swift 3 y 4

Establezca la supportedInterfaceOrientationspropiedad de UIViewControllers específicos como este:

class MyViewController: UIViewController {

    var orientations = UIInterfaceOrientationMask.portrait //or what orientation you want
    override var supportedInterfaceOrientations : UIInterfaceOrientationMask {
    get { return self.orientations }
    set { self.orientations = newValue }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    //...
}

ACTUALIZAR

Esta solución solo funciona cuando su noviewController está incrustado , porque la orientación hereda del viewController principal. Para este caso, puede crear una subclase de y establecer estas propiedades en él.UINavigationController
UINavigationViewController

Arash Etemad
fuente
Gracias. Esto funciona bien para mí porque solo quiero restringir una Vista específica a Retrato. No toda la aplicación.
user3204765
Todo lo que necesito es controlar controladores de vista específicos para bloquear la orientación independientemente de la orientación del dispositivo, ¡y esto funcionó muy bien!
Ryan B.
9

Agregue este código para forzar el retrato y bloquearlo:

override func viewDidLoad() {
    super.viewDidLoad()

    // Force the device in portrait mode when the view controller gets loaded
    UIDevice.currentDevice().setValue(UIInterfaceOrientation.Portrait.rawValue, forKey: "orientation") 
}

override func shouldAutorotate() -> Bool {
    // Lock autorotate
    return false
}

override func supportedInterfaceOrientations() -> Int {

    // Only allow Portrait
    return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}

override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {

    // Only allow Portrait
    return UIInterfaceOrientation.Portrait
}

En su AppDelegate, configure supportedInterfaceOrientationsForWindow en las orientaciones que desee que admita toda la aplicación:

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.All
} 
Valentin
fuente
Gracias Valentin, realmente aprecio tu ayuda, pero tu código no funcionó y ya lo resolví. También respondí a mi pregunta.
Thiha Aung
7

Esta es una solución genérica para su problema y otros relacionados.

1. Cree la clase auxiliar UIHelper y aplique los siguientes métodos:

    /**This method returns top view controller in application  */
    class func topViewController() -> UIViewController?
    {
        let helper = UIHelper()
        return helper.topViewControllerWithRootViewController(rootViewController: UIApplication.shared.keyWindow?.rootViewController)
    }

    /**This is a recursive method to select the top View Controller in a app, either with TabBarController or not */
    private func topViewControllerWithRootViewController(rootViewController:UIViewController?) -> UIViewController?
    {
        if(rootViewController != nil)
        {
            // UITabBarController
            if let tabBarController = rootViewController as? UITabBarController,
                let selectedViewController = tabBarController.selectedViewController {
                return self.topViewControllerWithRootViewController(rootViewController: selectedViewController)
            }

            // UINavigationController
            if let navigationController = rootViewController as? UINavigationController ,let visibleViewController = navigationController.visibleViewController {
                return self.topViewControllerWithRootViewController(rootViewController: visibleViewController)
            }

            if ((rootViewController!.presentedViewController) != nil) {
                let presentedViewController = rootViewController!.presentedViewController;
                return self.topViewControllerWithRootViewController(rootViewController: presentedViewController!);
            }else
            {
                return rootViewController
            }
        }

        return nil
    }

2. Crea un Protocolo con tu comportamiento deseado, pues tu caso específico será retrato.

orientación del protocoloIsOnlyPortrait {}

Nota: Si lo desea, agréguelo en la parte superior de UIHelper Class.

3. Amplíe su controlador de vista

En tu caso:

class Any_ViewController: UIViewController,orientationIsOnlyPortrait {

   ....

}

4. En la clase de delegado de la aplicación, agregue este método:

 func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        let presentedViewController = UIHelper.topViewController()
        if presentedViewController is orientationIsOnlyPortrait {
            return .portrait
        }
        return .all
    }

Notas finales:

  • Si esa clase más está en modo retrato, simplemente amplíe ese protocolo.
  • Si desea otros comportamientos de los controladores de vista, cree otros protocolos y siga la misma estructura.
  • Este ejemplo resuelve el problema con los cambios de orientación después de los controladores de vista push
Ariel Antonio Fundora
fuente
Me gusta esta solución, pero encontré las funciones UIHelper más útiles como extensiones para UINavigationController.
Michael Long
5

Un montón de excelentes respuestas en este hilo, pero ninguna satisfizo mis necesidades. Tengo una aplicación con pestañas con controladores de navegación en cada pestaña, y una vista necesitaba rotar, mientras que las otras debían estar bloqueadas en vertical. El controlador de navegación no estaba cambiando el tamaño de sus subvistas correctamente, por alguna razón. Encontré una solución (en Swift 3) al combinar con esta respuesta, y los problemas de diseño desaparecieron. Cree la estructura como lo sugiere @bmjohns:

import UIKit

struct OrientationLock {

    static func lock(to orientation: UIInterfaceOrientationMask) {
        if let delegate = UIApplication.shared.delegate as? AppDelegate {
            delegate.orientationLock = orientation
        }
    }

    static func lock(to orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation: UIInterfaceOrientation) {
        self.lock(to: orientation)
        UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")
    }
} 

Entonces subclase UITabBarController:

    import UIKit

class TabBarController: UITabBarController, UITabBarControllerDelegate {
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.delegate = self
    }

    func tabBarControllerSupportedInterfaceOrientations(_ tabBarController: UITabBarController) -> UIInterfaceOrientationMask {
        if tabBarController.selectedViewController is MyViewControllerNotInANavigationControllerThatShouldRotate {
            return .allButUpsideDown
        } else if let navController = tabBarController.selectedViewController as? UINavigationController, navController.topViewController is MyViewControllerInANavControllerThatShouldRotate {
            return .allButUpsideDown
        } else {
            //Lock view that should not be able to rotate
            return .portrait
        }
    }

    func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
        if viewController is MyViewControllerNotInANavigationControllerThatShouldRotate {
            OrientationLock.lock(to: .allButUpsideDown)
        } else if let navController = viewController as? UINavigationController, navController.topViewController is MyViewControllerInANavigationControllerThatShouldRotate {
            OrientationLock.lock(to: .allButUpsideDown)
        } else {
            //Lock orientation and rotate to desired orientation
            OrientationLock.lock(to: .portrait, andRotateTo: .portrait)
        }
        return true
    }
}

No olvide cambiar la clase de TabBarController en el guión gráfico a la subclase recién creada.

russdub
fuente
5

Para una nueva versión de Swift, pruebe esto

override var shouldAutorotate: Bool {
    return false
}

override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.portrait
}

override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
    return UIInterfaceOrientation.portrait
}
Khemmachart Chutapetch
fuente
¡Es exactamente lo que me necesitaba! Para el controlador de iPad, todas las opciones de orientación son válidas y para el controlador de iPhone solo en modo vertical escribiendo solo estas tres anulaciones: perfecto.
VYT
4

Aquí hay una forma simple que funciona para mí con Swift 4.2 (iOS 12.2), póngalo en un lugar UIViewControllerpara el que desea deshabilitar shouldAutorotate:

override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return .portrait
}

La .portraitparte le dice en qué orientación (es) permanecer, puede cambiar esto como desee. Las opciones son: .portrait, .all, .allButUpsideDown, .landscape, .landscapeLeft, .landscapeRight, .portraitUpsideDown.

GregT
fuente
2

Para configurar la orientación horizontal para todas las vistas de su aplicación y permitir solo una vista para todas las orientaciones (para poder agregar el carrete de la cámara, por ejemplo):

En AppDelegate.swift:

var adaptOrientation = false

En: didFinishLaunchingWithOptions

NSNotificationCenter.defaultCenter().addObserver(self, selector: "adaptOrientationAction:", name:"adaptOrientationAction", object: nil)

En otra parte de AppDelegate.swift:

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> Int {
    return checkOrientation(self.window?.rootViewController)
}

func checkOrientation(viewController:UIViewController?)-> Int{
    if (adaptOrientation == false){
        return Int(UIInterfaceOrientationMask.Landscape.rawValue)
    }else {
        return Int(UIInterfaceOrientationMask.All.rawValue)
    }
}

func adaptOrientationAction(notification: NSNotification){
    if adaptOrientation == false {
        adaptOrientation = true
    }else {
        adaptOrientation = false
    }
}

Luego, en la vista que sigue a la que desea poder tener todas las orientaciones:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
    if (segue.identifier == "YOURSEGUE") {
        NSNotificationCenter.defaultCenter().postNotificationName("adaptOrientationAction", object: nil)
    }
}

override func viewWillAppear(animated: Bool) {
    if adaptOrientation == true {
        NSNotificationCenter.defaultCenter().postNotificationName("adaptOrientationAction", object: nil)
    }
}

Lo último es marcar Orientación del dispositivo: - Vertical - Horizontal izquierda - Horizontal derecha

Flujo de iOS
fuente
2

Crear nueva extensión con

import UIKit

extension UINavigationController {
    override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return .portrait
    }
}

extension UITabBarController {
    override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return .portrait
    }
}
Felipe Kimio
fuente
1

bmjohns -> Tú eres mi salvador. Esa es la única solución que funciona (con la estructura AppUtility)

He creado esta clase:

class Helper{
    struct AppUtility {

        static func lockOrientation(_ orientation: UIInterfaceOrientationMask) {

            if let delegate = UIApplication.shared.delegate as? AppDelegate {
                delegate.orientationLock = orientation
            }
        }

        /// OPTIONAL Added method to adjust lock and rotate to the desired orientation
        static func lockOrientation(_ orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation:UIInterfaceOrientation) {

            self.lockOrientation(orientation)

            UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")
        }

    }
}

y siguió sus instrucciones, y todo funciona perfectamente para Swift 3 -> xcode versión 8.2.1

Stjepan
fuente
1

A partir de iOS 10 y 11, el iPad admite Slide Over y Split View. Para habilitar una aplicación en Slide Over y Split View, Requires full screen debe estar desmarcada. Eso significa que la respuesta aceptada no se puede usar si la aplicación quiere admitir Slide Over y Split View. Vea más de Apple Adopting Multitasking Enhancements en iPad aquí .

Tengo una solución que permite (1) desmarcar Requires full screen, (2) implementar solo una función appDelegate(especialmente si no desea / no puede modificar los controladores de vista de destino) y (3) evitar llamadas recursivas. Sin necesidad de clases auxiliares ni extensiones.

appDelegate.swift (Swift 4)

func application(_ application: UIApplication,
                 supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
    // Search for the visible view controller
    var vc = window?.rootViewController
    // Dig through tab bar and navigation, regardless their order 
    while (vc is UITabBarController) || (vc is UINavigationController) {
        if let c = vc as? UINavigationController {
            vc = c.topViewController
        } else if let c = vc as? UITabBarController {
            vc = c.selectedViewController
        }
    }
    // Look for model view controller
    while (vc?.presentedViewController) != nil {
        vc = vc!.presentedViewController
    }
    print("vc = " + (vc != nil ? String(describing: type(of: vc!)) : "nil"))
    // Final check if it's our target class.  Also make sure it isn't exiting.
    // Otherwise, system will mistakenly rotate the presentingViewController.
    if (vc is TargetViewController) && !(vc!.isBeingDismissed) {
        return [.portrait]
    }
    return [.all]
}

Editar

@bmjohns señaló que esta función no se llama en iPad. Verifiqué y sí no se llamó. Entonces, hice un poco más de pruebas y descubrí algunos hechos:

  1. Desmarqué Requires full screenporque quiero habilitar Slide Over y Slide View en iPad. Eso requiere la aplicación para apoyar a los 4 orientación para el iPad, en Info.plist: Supported interface orientations (iPad).

Mi aplicación funciona de la misma manera que Facebook: en iPhone, la mayoría de las veces está bloqueada en modo vertical. Al ver la imagen en pantalla completa, permite a los usuarios rotar el paisaje para ver mejor. En iPad, los usuarios pueden rotar a cualquier orientación en cualquier controlador de vista. Por lo tanto, la aplicación se ve bien cuando el iPad está colocado sobre Smart Cover (horizontal a la izquierda).

  1. Para que iPad llame application(_:supportedInterfaceOrientationsFor), en Info.plist, solo mantenga retrato para iPad. La aplicación perderá la capacidad Slide Over + Split View. Pero puede bloquear o desbloquear la orientación para cualquier controlador de vista, en un solo lugar y sin necesidad de modificar la clase ViewController.

  2. Finalmente, esta función se llama en el ciclo de vida del controlador de vista, cuando se muestra / elimina la vista. Si su aplicación necesita bloquear / desbloquear / cambiar la orientación en otro momento, es posible que no funcione

John Pang
fuente
¿Funciona para iPhone? Quiero mostrar uno de mis viewController solo en paisaje.
The iCoder
Si. funciona para iPhone. Quiero uno de mis controladores de vista tanto en retrato como en paisaje, y volver al retrato después de descartarlo.
John Pang
1

Solución real probada para esto . En mi ejemplo, necesito que toda la aplicación esté en modo vertical, pero solo la orientación de una pantalla debe estar en modo horizontal. Haga una orientación vertical para la aplicación, marcando solo el modo vertical

Codifique en AppDelegate como se describen las respuestas anteriores.

var orientationLock = UIInterfaceOrientationMask.all

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask 
{
  return self.orientationLock
}
struct AppUtility {  

static func lockOrientation(_ orientation: UIInterfaceOrientationMask) {
    if let delegate = UIApplication.shared.delegate as? AppDelegate {
        delegate.orientationLock = orientation
    }
}
static func lockOrientation(_ orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation:UIInterfaceOrientation) {
self.lockOrientation(orientation)     
UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")
}  
}

Luego, escriba este código antes de que se presente / presione el controlador de vista de orientación horizontal.

override func viewWillAppear(_ animated: Bool) {  
super.viewWillAppear(animated)
AppDelegate.AppUtility.lockOrientation(UIInterfaceOrientationMask.portrait, andRotateTo: UIInterfaceOrientation.portrait)
}  

Luego, escriba este código en el controlador de vista real (para vista horizontal)

override func viewWillAppear(_ animated: Bool) {  
super.viewWillAppear(animated)
AppDelegate.AppUtility.lockOrientation(UIInterfaceOrientationMask.landscape, andRotateTo: UIInterfaceOrientation.landscape)
}  
Gurpreet Singh
fuente
1

Experimenté un poco y logré encontrar una solución limpia para este problema. El enfoque se basa en el etiquetado de vista a través de vista-> etiqueta

En el ViewController de destino, simplemente asigne la etiqueta a la vista raíz como en el siguiente ejemplo de código:

class MyViewController: BaseViewController {

  // declare unique view tag identifier
  static let ViewTag = 2105981;

  override func viewDidLoad()
  {
    super.viewDidLoad();
    // assign the value to the current root view
    self.view.tag = MyViewController.ViewTag;
  }

Y finalmente en AppDelegate.swift verifique si la vista que se muestra actualmente es la que etiquetamos:

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask
{
    if (window?.viewWithTag(DesignerController.ViewTag)) != nil {
        return .portrait;
    }
    return .all;
}

Este enfoque ha sido probado con mi simulador y parece que funciona bien.

Nota: la vista marcada también se encontrará si el MVC actual se superpone con algún ViewController secundario en la pila de navegación.

Vlada
fuente
0

Gracias a la respuesta de @ bmjohn anterior. Aquí hay una versión de Xamarin / C # funcional del código de esa respuesta, para ahorrarles a otros el tiempo de transcripción:

AppDelegate.cs

 public UIInterfaceOrientationMask OrientationLock = UIInterfaceOrientationMask.All;
 public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations(UIApplication application, UIWindow forWindow)
 {
     return this.OrientationLock;
 }

Clase Static OrientationUtility.cs:

public static class OrientationUtility
{
    public static void LockOrientation(UIInterfaceOrientationMask orientation)
    {
        var appdelegate = (AppDelegate) UIApplication.SharedApplication.Delegate;
        if(appdelegate != null)
        {
            appdelegate.OrientationLock = orientation;
        }
    }

    public static void LockOrientation(UIInterfaceOrientationMask orientation, UIInterfaceOrientation RotateToOrientation)
    {
        LockOrientation(orientation);

        UIDevice.CurrentDevice.SetValueForKey(new NSNumber((int)RotateToOrientation), new NSString("orientation"));
    }
}

Ver controlador:

    public override void ViewDidAppear(bool animated)
    {
       base.ViewWillAppear(animated);
       OrientationUtility.LockOrientation(UIInterfaceOrientationMask.Portrait, UIInterfaceOrientation.Portrait);
    }

    public override void ViewWillDisappear(bool animated)
    {
        base.ViewWillDisappear(animated);
        OrientationUtility.LockOrientation(UIInterfaceOrientationMask.All);
    }
ccs_dev
fuente
¿No entiendo cómo esta respuesta es relevante? Esa persona preguntó en rápido y tú lo has dado en Xamarin.
Mihir Oza
0

La mejor solución para bloquear y cambiar la orientación en vertical y horizontal:

Vea este video en YouTube:

https://m.youtube.com/watch?v=4vRrHdBowyo

Este tutorial es mejor y más sencillo.

o use el siguiente código:

Ver esta imagen

// 1- en el segundo viewcontroller configuramos landscapeleft y en el primer viewcontroller configuramos portrat:

// 2- si usa NavigationController, debe agregar una extensión

import UIKit

class SecondViewController: UIViewController {


    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation")
    }

    override open var shouldAutorotate: Bool {
        return false
    }

    override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return .landscapeLeft
    }

    override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
        return .landscapeLeft
    }
    
    

    override func viewDidLoad() {
        super.viewDidLoad()
    }

//write The rest of your code in here


}

//if you use NavigationController, you should add this extension

extension UINavigationController {
    override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return topViewController?.supportedInterfaceOrientations ?? .allButUpsideDown
    
    }
}
OliaPh
fuente