web-dev-qa-db-fra.com

Définition de l'orientation du périphérique dans Swift iOS

Je travaille sur une application Swift pour iPhone. Il y a une vue modale dans mon application que je veux seulement être en vue portrait.

Ma question est la suivante: comment forcer par programmation le téléphone à ne pas autoriser la rotation? En d'autres termes, je recherche un code qui ne permet pas d'afficher une vue modale en mode paysage (activation du verrouillage de la rotation portrait).

Ceci est juste pour 1 vue modale, donc je ne peux pas désactiver la rotation pour l'application entière, sinon je désactiverais simplement la rotation complètement.

J'ai trouvé du code dans mes recherches ici Mais c'est dans l'Objectif C, au cas où cela aiderait. Merci!

61
rocket101

Vous pouvez coller ces méthodes dans le ViewController de chaque vue devant être en mode portrait:

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

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

Salut pour LandscapeLeft et LandscapeRight (Mise à jour Swift 2.0)

enter image description here Et vous avez ceci dans info 

enter image description here

Et UIController

override func shouldAutorotate() -> Bool {
    return true
}

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return [UIInterfaceOrientationMask.LandscapeLeft,UIInterfaceOrientationMask.LandscapeRight]
}

Pour PortraitUpsideDown et Portrait, utilisez-le enter image description here

override func shouldAutorotate() -> Bool {
    if (UIDevice.currentDevice().orientation == UIDeviceOrientation.LandscapeLeft ||
        UIDevice.currentDevice().orientation == UIDeviceOrientation.LandscapeRight ||
        UIDevice.currentDevice().orientation == UIDeviceOrientation.Unknown) {
            return false
    }
    else {
        return true
    }
}

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return [UIInterfaceOrientationMask.Portrait ,UIInterfaceOrientationMask.PortraitUpsideDown]
}

Message de la France, joyeux Noël!

Modifier :

Autre solution:

extension UINavigationController {
    public override func shouldAutorotate() -> Bool {
        if visibleViewController is MyViewController {
            return true   // rotation
        } else {
            return false  // no rotation
        }
    }

    public override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        return (visibleViewController?.supportedInterfaceOrientations())!
    }
}
67
YannickSteph

Swift 3

La rotation d'orientation est plus compliquée si un contrôleur de vue est incorporé dans UINavigationController ou UITabBarController, le contrôleur de navigation ou la barre de tabulation a priorité et prend les décisions en matière d'autorotation et d'orientations prises en charge.

Utilisez les extensions suivantes sur UINavigationController et UITabBarController pour que les contrôleurs de vue intégrés à l'un de ces contrôleurs puissent prendre les décisions suivantes:

Extension UINavigationController

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

Extension UITabBarController

extension UITabBarController {

override open var shouldAutorotate: Bool {
    get {
        if let selectedVC = selectedViewController{
            return selectedVC.shouldAutorotate
        }
        return super.shouldAutorotate
    }
}

override open var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation{
    get {
        if let selectedVC = selectedViewController{
            return selectedVC.preferredInterfaceOrientationForPresentation
        }
        return super.preferredInterfaceOrientationForPresentation
    }
}

override open var supportedInterfaceOrientations: UIInterfaceOrientationMask{
    get {
        if let selectedVC = selectedViewController{
            return selectedVC.supportedInterfaceOrientations
        }
        return super.supportedInterfaceOrientations
    }
}}

Désormais, vous pouvez remplacer les attributs supportedInterfaceOrientations, shouldAutoRotate et preferredInterfaceOrientationForPresentation dans le contrôleur de vue à verrouiller, sinon vous pouvez omettre les remplacements dans les autres contrôleurs de vue dont vous souhaitez hériter le comportement d'orientation par défaut spécifié dans la pliste de votre application.

Verrouiller à l'orientation spécifique

class YourViewController: UIViewController {
open override var supportedInterfaceOrientations: UIInterfaceOrientationMask{
    get {
        return .portrait
    }
}}

Désactiver la rotation

    class YourViewController: UIViewController {
open override var shouldAutorotate: Bool {
    get {
        return false
    }
}}

Modifier l'orientation de l'interface préférée pour la présentation

class YourViewController: UIViewController {
open override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation{
    get {
        return .portrait
    }
}}
40
Dragos

Le code ci-dessus risque de ne pas fonctionner si votre contrôleur de vue appartient à un contrôleur de navigation. Si c'est le cas, il doit obéir aux règles du contrôleur de navigation, même s'il possède des règles d'orientation différentes. Une meilleure approche serait de laisser le contrôleur de vue décider par lui-même et le contrôleur de navigation utilisera la décision du contrôleur de vue le plus haut. 

Nous pouvons prendre en charge le verrouillage sur l’orientation actuelle et l’autorotation pour verrouiller une orientation spécifique avec cette extension générique sur UINavigationController: -:

extension UINavigationController {
            public override func shouldAutorotate() -> Bool {
                return visibleViewController.shouldAutorotate()
            }

        public override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
            return (visibleViewController?.supportedInterfaceOrientations())!
        }
    }

Maintenant, dans votre contrôleur de vue, nous pouvons 

class ViewController: UIViewController {
    // MARK: Autoroate configuration

    override func shouldAutorotate() -> Bool {
        if (UIDevice.currentDevice().orientation == UIDeviceOrientation.Portrait ||
            UIDevice.currentDevice().orientation == UIDeviceOrientation.PortraitUpsideDown ||
            UIDevice.currentDevice().orientation == UIDeviceOrientation.Unknown) {
                return true
        }
        else {
            return false
        }
    }

    override func supportedInterfaceOrientations() -> Int {
        return Int(UIInterfaceOrientationMask.Portrait.rawValue) | Int(UIInterfaceOrientationMask.PortraitUpsideDown.rawValue)
    }
}

J'espère que ça aide . Merci

18
Vivek Parihar

Si quelqu'un veut la réponse, je pense que je viens de l'obtenir. Essaye ça:

  • Allez dans votre fichier .plist et vérifiez toutes les orientations.
  • Dans le contrôleur de vue pour lequel vous souhaitez forcer l'orientation, ajoutez le code suivant:
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.Portrait.toRaw().hashValue | UIInterfaceOrientationMask.PortraitUpsideDown.toRaw().hashValue
}

J'espère que ça aide !

MODIFIER :

Pour forcer la rotation, utilisez le code suivant:

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

Cela fonctionne pour iOS 7 et 8!

11
lobodart

Cela désactivera l'autorotation de la vue:

override func shouldAutorotate() -> Bool {
    return false;
}

Mettre à jour

override func shouldAutorotate() -> Bool {
    if (UIDevice.currentDevice().orientation == UIDeviceOrientation.LandscapeLeft ||
        UIDevice.currentDevice().orientation == UIDeviceOrientation.LandscapeRight ||
        UIDevice.currentDevice().orientation == UIDeviceOrientation.Unknown) {
            return false;
    }
    else {
        return true;
    }
}

Si l'application est en mode paysage et que vous affichez une vue qui doit être affichée en mode portrait, cela permettra à l'application de changer son orientation en portrait (bien sûr, lorsque l'appareil sera pivoté dans cette orientation). 

11
tesla

 enter image description here

Go to your pList and add or remove the following as per your requirement:

"Supported Interface Orientations" - Array
"Portrait (bottom home button)" - String
"Portrait (top home button)" - String
"Supported Interface Orientations (iPad)" - Array
"Portrait (bottom home button)" - String
"Portrait (top home button)" - String
"Landscape (left home button)" - String
"Landscape (right home button)" - String

Remarque: cette méthode permet la rotation de toute une application. 

OR

Créez un ParentViewController pour UIViewControllers dans un projet .__ (méthode d'héritage).

//  UIappViewController.Swift

import UIKit

class UIappViewController: UIViewController {
          super.viewDidLoad()   
    }
//Making methods to lock Device orientation.
    override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        return UIInterfaceOrientationMask.Portrait
    }
    override func shouldAutorotate() -> Bool {
        return false
    }                                                                                                                                       
    override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    }

Associez le contrôleur parent de chaque contrôleur de vue en tant que UIappViewController.

//  LoginViewController.Swift

import UIKit
import Foundation

class LoginViewController: UIappViewController{

    override func viewDidLoad()
    {
        super.viewDidLoad()

    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
9
A.G

Pour Swift 3, iOS 10 

override open var shouldAutorotate: Bool {
    return false
}

override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return .portrait
}

override open var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
    return .portrait
}

Cependant, un problème avec le paramètre shouldAutorotate ne fonctionne pas sur iOS 9 pour le moment.

8
CodeOverRide

Dans le fichier info.plist, modifiez les orientations souhaitées dans "orientation d'interface prise en charge".

Dans Swift, la manière de gérer les fichiers-> info.plist-> prend en charge l'orientation de l'interface.

6
Malu

Plus version Swift-like:

override func shouldAutorotate() -> Bool {
    switch UIDevice.currentDevice().orientation {
    case .Portrait, .PortraitUpsideDown, .Unknown:
        return true
    default:
        return false
    }
}

override func supportedInterfaceOrientations() -> Int {
    return Int(UIInterfaceOrientationMask.Portrait.rawValue) | Int(UIInterfaceOrientationMask.PortraitUpsideDown.rawValue)
}

UINavigationController de Vivek Parihar

extension UINavigationController {
    public override func shouldAutorotate() -> Bool {
        return visibleViewController.shouldAutorotate()
    }
}
4
Vojtech Vrbka

Je me suis battu toute la matinée pour que SEUL paysage soit pris en charge correctement. J'ai découvert quelque chose d'énervant. bien que l'onglet "Général" vous permette de désélectionner "Portrait" pour l'orientation du périphérique, vous devez modifier la plist elle-même pour désactiver les orientations Portrait et PortraitUpsideDown INTERFACE.

L'autre chose est qu'il semble que vous deviez utiliser les versions "masque" des énumérations (par exemple, UIInterfaceOrientationMask.LandscapeLeft), et pas seulement celle d'orientation. Le code qui l'a fait fonctionner pour moi (dans mon viewController principal):

override func shouldAutorotate() -> Bool {
    return true
}

override func supportedInterfaceOrientations() -> Int {
    return Int(UIInterfaceOrientationMask.LandscapeLeft.rawValue) | Int(UIInterfaceOrientationMask.LandscapeRight.rawValue)
}

Faire cette combinaison de changements de plist et de code est le seul moyen de le faire fonctionner correctement.

4
mrwheet

// Swift 2

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    let orientation: UIInterfaceOrientationMask =
    [UIInterfaceOrientationMask.Portrait, UIInterfaceOrientationMask.PortraitUpsideDown]
    return orientation
}
3
user3561494

Deux suggestions avec la solution de @Vivek Parihar:

  1. Si nous présentons un viewController, nous devrions cocher nil “visibleViewController” dans l'extension navigationController 

    extension UINavigationController {
    public override func shouldAutorotate() -> Bool {
        var shouldAutorotate = false
        if visibleViewController != nil {
            shouldAutorotate = visibleViewController.shouldAutorotate()
        }
        return shouldAutorotate
    }
    
    public override func supportedInterfaceOrientations() -> Int {
        return visibleViewController.supportedInterfaceOrientations()
    }
    }
    
  2. Si nous utilisons une feuille d'action à présenter et que l'utilisateur effectuera une rotation upsideDown, votre feuille d'action s'ouvrira à partir du bord supérieur de l'écran: P, pour résoudre ce problème, nous devons uniquement prendre Portrait

    override func shouldAutorotate() -> Bool {
    if (UIDevice.currentDevice().orientation == UIDeviceOrientation.Portrait ||
        UIDevice.currentDevice().orientation == UIDeviceOrientation.Unknown) {
            return true
    }
    else {
        return false
    }
    

    }

    override func supportedInterfaceOrientations() -> Int {
        return Int(UIInterfaceOrientationMask.Portrait.rawValue)
    }
    
2
Nitesh

Swift 2.2 

    func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {

    if self.window?.rootViewController?.presentedViewController is SignatureLandscapeViewController {

        let secondController = self.window!.rootViewController!.presentedViewController as! SignatureLandscapeViewController

        if secondController.isPresented {

            return UIInterfaceOrientationMask.LandscapeLeft;

        } else {

            return UIInterfaceOrientationMask.Portrait;
        }

    } else {

        return UIInterfaceOrientationMask.Portrait;
    }
}
0
idris yıldız

Depuis ios 10.0, nous avons besoin de set { self.orientations = newValue } pour définir l’orientation. Assurez-vous que la propriété paysage est activée dans votre projet.

private var orientations = UIInterfaceOrientationMask.landscapeLeft
override var supportedInterfaceOrientations : UIInterfaceOrientationMask {
    get { return self.orientations }
    set { self.orientations = newValue }
}
0
Jack

Mon humble contribution (Xcode 8, Swift 3):

func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        if let rootViewController = self.topViewControllerWithRootViewController(rootViewController: window?.rootViewController) {
            if (rootViewController.responds(to: Selector(("canRotate")))) {
                // Unlock landscape view orientations for this view controller
                return .allButUpsideDown;
            }
        }
        return .portrait;        
    }

    private func topViewControllerWithRootViewController(rootViewController: UIViewController!) -> UIViewController? {
        if (rootViewController == nil) { return nil }
        if (rootViewController.isKind(of: (UITabBarController).self)) {
            return topViewControllerWithRootViewController(rootViewController: (rootViewController as! UITabBarController).selectedViewController)
        } else if (rootViewController.isKind(of:(UINavigationController).self)) {
            return topViewControllerWithRootViewController(rootViewController: (rootViewController as! UINavigationController).visibleViewController)
        } else if (rootViewController.presentedViewController != nil) {
            return topViewControllerWithRootViewController(rootViewController: rootViewController.presentedViewController)
        }
        return rootViewController
    }

... sur l'AppDelegate. Tous les crédits pour Gandhi Mena: http://www.jairobjunior.com/blog/2016/03/05/how-to-rotate-only-one-view-controller-to-landscape-in-ios-slash -Rapide/

0
Ivan Morales

Swift 4:

La réponse la plus simple, dans mon cas, ayant besoin de s'assurer qu'un didacticiel d'intégration était en mode portrait uniquement:

extension myViewController {
    //manage rotation for this viewcontroller
    override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return .portrait
    }
}

Eezy-peezy.

0
drew..