ios swift landscape

ios - Forzar el modo horizontal en un ViewController usando Swift



landscape (16)

Swift 4

override func viewDidLoad() { super.viewDidLoad() let value = UIInterfaceOrientation.landscapeLeft.rawValue UIDevice.current.setValue(value, forKey: "orientation") } override var supportedInterfaceOrientations: UIInterfaceOrientationMask { return .landscapeLeft } override var shouldAutorotate: Bool { return true }

// Si su vista está incrustada en un controlador de navegación, lo anterior solo no funcionará. tienes que subir en cascada // Entonces agrega la siguiente extensión después de la definición de clase

extension UINavigationController { override open var shouldAutorotate: Bool { get { if let visibleVC = visibleViewController { return visibleVC.shouldAutorotate } return super.shouldAutorotate } } override open var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation{ get { if let visibleVC = visibleViewController { return visibleVC.preferredInterfaceOrientationForPresentation } return super.preferredInterfaceOrientationForPresentation } } override open var supportedInterfaceOrientations: UIInterfaceOrientationMask{ get { if let visibleVC = visibleViewController { return visibleVC.supportedInterfaceOrientations } return super.supportedInterfaceOrientations } }}

Swift 3

override func viewDidLoad() { super.viewDidLoad() let value = UIInterfaceOrientation.landscapeLeft.rawValue UIDevice.current.setValue(value, forKey: "orientation") } private func supportedInterfaceOrientations() -> UIInterfaceOrientationMask { return UIInterfaceOrientationMask.landscapeLeft } private func shouldAutorotate() -> Bool { return true }

Estoy tratando de forzar solo una vista en mi aplicación en modo horizontal, estoy llamando

override func shouldAutorotate() -> Bool { print("shouldAutorotate") return false } override func supportedInterfaceOrientations() -> Int { print("supportedInterfaceOrientations") return Int(UIInterfaceOrientationMask.LandscapeLeft.rawValue) } override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation { return UIInterfaceOrientation.LandscapeLeft }

La vista se inicia en modo vertical y sigue girando cuando cambio la orientación del dispositivo.
El shouldAutorotate nunca se llama.
Cualquier ayuda sería apreciada.


De acuerdo con la documentación de shouldAutorotate método shouldAutorotate debe devolver true o YES en Objective-C para que se consideren las shouldAutorotate .


En AppDelegate agregue esto

//Orientation Variables var myOrientation: UIInterfaceOrientationMask = .portrait func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { return myOrientation }

Agregue esto en viewController, que desea cambiar la orientación

override func viewDidLoad() { super.viewDidLoad() self.rotateToLandsScapeDevice() } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) self.rotateToPotraitScapeDevice() } func rotateToLandsScapeDevice(){ let appDelegate = UIApplication.shared.delegate as! AppDelegate appDelegate.myOrientation = .landscapeLeft UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation") UIView.setAnimationsEnabled(true) } func rotateToPotraitScapeDevice(){ let appDelegate = UIApplication.shared.delegate as! AppDelegate appDelegate.myOrientation = .portrait UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation") UIView.setAnimationsEnabled(true) }


En ViewController en viewDidLoad Method, llame a la siguiente función

func rotateDevice(){ UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation") UIView.setAnimationsEnabled(true) // while rotating device it will perform the rotation animation }`

Aplicación Delegar archivo Agregar a continuación Función y variables

//Orientation Variables var orientationLock = UIInterfaceOrientationMask.portrait var myOrientation: UIInterfaceOrientationMask = .portrait func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { return .landscape }


Funciona en Swift 2.2

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask { if self.window?.rootViewController?.presentedViewController is SignatureViewController { let secondController = self.window!.rootViewController!.presentedViewController as! SignatureViewController if secondController.isPresented { return UIInterfaceOrientationMask.LandscapeLeft; } else { return UIInterfaceOrientationMask.Portrait; } } else { return UIInterfaceOrientationMask.Portrait; } }


Me enfrenté a un problema similar en mi proyecto. Solo tiene soporte para retrato. La estructura de ViewController es que, Navigation contenía un controlador (lo llamé A) y una vista de desplazamiento larga en un controlador. Necesito A (retrato) presente a B (paisaje a la derecha).

Al principio probé el siguiente método y parecía funcionar, pero finalmente encontré un error.

Swift 5 y iOS12

// In B controller just override three properties override var shouldAutorotate: Bool { return false } override var supportedInterfaceOrientations: UIInterfaceOrientationMask { return UIInterfaceOrientationMask.landscapeRight } override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation { return .landscapeRight }

Y entonces algo se vuelve extraño. Cuando el controlador B descarta al controlador A. El ScrollView en el controlador A se ha deslizado en algún momento.

Entonces utilicé otro método, así que gire la pantalla cuando viewWillAppear . Puede ver el código para eso a continuación.

// In controller B // not need override shouldAutorotate , supportedInterfaceOrientations , preferredInterfaceOrientationForPresentation override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) let appDel = UIApplication.shared.delegate as! AppDelegate appDel.currentOrientation = .landscapeRight UIDevice.current.setValue( UIInterfaceOrientation.landscapeRight.rawValue, forKey: "orientation") UIViewController.attemptRotationToDeviceOrientation() } //in viewWillDisappear rotate to portrait can not fix the bug override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) { let appDel = UIApplication.shared.delegate as! AppDelegate appDel.currentOrientation = .portrait UIDevice.current.setValue( UIInterfaceOrientation.portrait.rawValue, forKey: "orientation") UIViewController.attemptRotationToDeviceOrientation() //must call super.dismiss(animated: true, completion: nil) }

// in AppDelegate // the info plist is only supported portrait also, No need to change it var currentOrientation : UIInterfaceOrientationMask = .portrait func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { return self.currentOrientation }


Mi solucion es

acaba de agregar los siguientes códigos en AppDelegate

enum PossibleOrientations { case portrait case landscape func o() -> UIInterfaceOrientationMask { switch self { case .portrait: return .portrait case .landscape: return .landscapeRight } } } var orientation: UIInterfaceOrientationMask = .portrait func switchOrientation(to: PossibleOrientations) { let keyOrientation = "orientation" if to == .portrait && UIDevice.current.orientation.isPortrait { return } else if to == .landscape && UIDevice.current.orientation.isLandscape { return } switch to { case .portrait: orientation = .portrait UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: keyOrientation) case .landscape: orientation = .landscapeRight UIDevice.current.setValue(UIInterfaceOrientation.landscapeRight.rawValue, forKey: keyOrientation) } }

Y llame a los códigos a continuación para cambiar

override func viewDidLoad() { super.viewDidLoad() if let appDelegate = UIApplication.shared.delegate as? AppDelegate { appDelegate.switchOrientation(to: .landscape) } }

o como abajo

@IBAction func actBack() { if let appDelegate = UIApplication.shared.delegate as? AppDelegate { appDelegate.switchOrientation(to: .portrait) } self.navigationController?.popViewController(animated: true) }


Necesitaba forzar un controlador a la orientación vertical. Agregar esto funcionó para mí.

Swift 4 con iOS 11

override var supportedInterfaceOrientations : UIInterfaceOrientationMask{ return .portrait }


Para mí, los mejores resultados vinieron de combinar la respuesta de Zeesha y la respuesta de sazz.

Agregue las siguientes líneas a AppDelegate.swift:

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

Agregue la siguiente línea a su clase de controlador de vista:

let appDel = UIApplication.shared.delegate as! AppDelegate

Agregue las siguientes líneas a viewDidLoad() su controlador de viewDidLoad() :

appDel.myOrientation = .landscape UIDevice.current.setValue(UIInterfaceOrientation.landscapeLeft.rawValue, forKey: "orientation")

(opcional) Agregue esta línea a su función de descarte:

appDel.myOrientation = .portrait UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation")

Lo que hacen estas líneas de código es establecer la orientación predeterminada en vertical, rotarla horizontalmente cuando se carga el controlador de vista y, finalmente, restablecerla nuevamente en vertical una vez que se cierra el controlador de vista.


Puede ser útil para otros, encontré una manera de forzar que la vista se inicie en modo horizontal:

Pon esto en la vistaDidLoad ():

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

y,

override var shouldAutorotate: Bool { return true }


Swift 3. Esto bloquea la orientación cada vez que el usuario vuelve a abrir la aplicación.

class MyViewController: UIViewController { ... override func viewDidLoad() { super.viewDidLoad() // Receive notification when app is brought to foreground NotificationCenter.default.addObserver(self, selector: #selector(self.onDidBecomeActive), name: NSNotification.Name.UIApplicationDidBecomeActive, object: nil) } // Handle notification func onDidBecomeActive() { setOrientationLandscape() } // Change orientation to landscape private func setOrientationLandscape() { if !UIDevice.current.orientation.isLandscape { let value = UIInterfaceOrientation.landscapeLeft.rawValue UIDevice.current.setValue(value, forKey:"orientation") UIViewController.attemptRotationToDeviceOrientation() } } // Only allow landscape left override var supportedInterfaceOrientations: UIInterfaceOrientationMask { return UIInterfaceOrientationMask.landscapeLeft } /* // Allow rotation - this seems unnecessary private func shouldAutoRotate() -> Bool { return true } */ ... }


Swift 4

Intentando mantener la orientación, nada funcionó, pero esto para mí:

... override func viewDidLoad() { super.viewDidLoad() forcelandscapeRight() let notificationCenter = NotificationCenter.default notificationCenter.addObserver(self, selector: #selector(forcelandscapeRight), name: Notification.Name.UIDeviceOrientationDidChange, object: nil) } @objc func forcelandscapeRight() { let value = UIInterfaceOrientation.landscapeRight.rawValue UIDevice.current.setValue(value, forKey: "orientation") } ....


Usando Swift 2.2

Tratar:

let value = UIInterfaceOrientation.LandscapeLeft.rawValue UIDevice.currentDevice().setValue(value, forKey: "orientation")

Seguido por:

UIViewController.attemptRotationToDeviceOrientation()

De la referencia de clase UIViewController de Apple:

Algunos controladores de vista pueden querer usar condiciones específicas de la aplicación para determinar qué orientaciones de interfaz son compatibles. Si su controlador de vista hace esto, cuando esas condiciones cambien, su aplicación debería llamar a este método de clase. El sistema intenta rotar inmediatamente a la nueva orientación.

Luego, como otros han sugerido, anule los siguientes métodos según corresponda:

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask { return UIInterfaceOrientationMask.LandscapeLeft } override func shouldAutorotate() -> Bool { return true }

Estaba teniendo un problema similar con una vista de firma y esto me resolvió.


Swift 4 , probado en iOS 11

Puede especificar la orientación en projectTarget -> General -> DeploymentInfo (Orientación del dispositivo) -> Vertical (Landscapeleft y Landscaperight son opcionales)

AppDelegate

var myOrientation: UIInterfaceOrientationMask = .portrait func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { return myOrientation }

LandScpaeViewController

override func viewDidLoad() { super.viewDidLoad() let appDelegate = UIApplication.shared.delegate as! AppDelegate appDelegate.myOrientation = .landscape }

OnDismissButtonTap

let appDelegate = UIApplication.shared.delegate as! AppDelegate appDelegate.myOrientation = .portrait

Eso es. :)


// below code put in view controller // you can change landscapeLeft or portrait override func viewWillAppear(_ animated: Bool) { UIDevice.current.setValue(UIInterfaceOrientation.landscapeRight.rawValue, forKey: "orientation") } override var shouldAutorotate: Bool { return true } override var supportedInterfaceOrientations: UIInterfaceOrientationMask { return .landscapeRight } override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation { return .landscapeRight }


class CustomUIViewController : UIViewController{ override var supportedInterfaceOrientations : UIInterfaceOrientationMask{ return .landscapeLeft } } class ViewController: CustomUIViewController { . . . }