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 {
.
.
.
}