Comment forcer l'orientation du contrôleur de vue dans iOS 8?

Avant iOS 8, nous utilisions le code ci-dessous en conjonction avec les méthodes supportedInterfaceOrientations et shouldAutoRotate delegate pour forcer l'orientation de l'application à une orientation particulière. J'ai utilisé ci-dessous l'extrait de code pour faire pivoter l'application par programme à l'orientation souhaitée. Tout d'abord, je change l'orientation de la barre d'état. Et puis le simple fait de présenter et de rejeter immédiatement une vue modale fait pivoter la vue vers l'orientation souhaitée.

[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:YES];
UIViewController *c = [[UIViewController alloc]init];
[self presentViewController:vc animated:NO completion:nil];
[self dismissViewControllerAnimated:NO completion:nil];

Mais cela échoue dans iOS 8. En outre, j'ai vu quelques réponses dans stack overflow où les gens ont suggéré que nous devrions toujours éviter cette approche à partir d'iOS 8.

Pour être plus précis, mon application est un type d'application Universel. Il y a trois contrôleurs au total.

  1. First View controller - il devrait prendre en charge toutes les orientations dans l'iPad et seulement le portrait (bouton d'accueil vers le bas) dans l'iPhone.

  2. Second View controller - il ne devrait supporter que le paysage droit dans toutes les conditions

  3. Troisième contrôleur de vue - il ne devrait prendre en charge que le paysage dans toutes les conditions

Nous utilisons le contrôleur de navigation pour la navigation de page. Du premier contrôleur de vue, sur une action de clic de bouton, nous poussons le second sur la pile. Ainsi, lorsque le second contrôleur de vue arrive, quelle que soit l'orientation de l'appareil, l'application doit se verrouiller en paysage uniquement.

Voici mes méthodes shouldAutorotate et supportedInterfaceOrientations en seconde et troisième contrôleur de vue.

-(NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskLandscapeRight;
}

-(BOOL)shouldAutorotate {
    return NO;
}

Existe-t-il une solution pour cela ou une meilleure façon de verrouiller un contrôleur de vue en particulier l'orientation pour iOS 8. S'il vous plaît aider!!

134
demandé sur Sunny Shah 2014-10-14 13:26:49

24 réponses

Pour iOS 7-10:

Objectif-C:

[[UIDevice currentDevice] setValue:@(UIInterfaceOrientationLandscapeLeft) forKey:@"orientation"];
[UINavigationController attemptRotationToDeviceOrientation];

Swift 3:

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

Appelez-le simplement dans - viewDidAppear: du contrôleur de vue présenté.

285
répondu Sunny Shah 2018-03-14 03:43:51

La rotation D'Orientation est un peu plus compliquée si vous êtes à l'intérieur d'un UINavigationController ou UITabBarController. Le problème est que si un contrôleur de vue est intégré dans l'un de ces contrôleurs, le contrôleur de navigation ou de barre d'onglets a la priorité et prend les décisions sur l'autorotation et les orientations prises en charge.

J'utilise les 2 extensions suivantes sur UINavigationController et UITabBarController afin que les contrôleurs de vue incorporés dans l'un de ces contrôleurs puissent faire le décision.

Donnez le pouvoir aux contrôleurs de vue!

Swift 2.3

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

extension UITabBarController {
    public override func supportedInterfaceOrientations() -> Int {
        if let selected = selectedViewController {
            return selected.supportedInterfaceOrientations()
        }
        return super.supportedInterfaceOrientations()
    }
    public override func shouldAutorotate() -> Bool {
        if let selected = selectedViewController {
            return selected.shouldAutorotate()
        }
        return super.shouldAutorotate()
    }
}

Swift 3

extension UINavigationController {
    open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        return visibleViewController?.supportedInterfaceOrientations ?? super.supportedInterfaceOrientations
    }

    open override var shouldAutorotate: Bool {
        return visibleViewController?.shouldAutorotate ?? super.shouldAutorotate
    }
}

extension UITabBarController {
    open override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        if let selected = selectedViewController {
            return selected.supportedInterfaceOrientations
        }
        return super.supportedInterfaceOrientations
    }

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

Maintenant, vous pouvez remplacer la méthode supportedInterfaceOrientations ou vous pouvez remplacer shouldAutoRotate dans le contrôleur de vue que vous souhaitez verrouiller sinon vous pouvez omettre les remplacements dans les autres contrôleurs de vue que vous souhaitez hériter du comportement d'orientation par défaut spécifié dans le plist{[9 de votre application]}

Désactiver La Rotation

class ViewController: UIViewController {
    override func shouldAutorotate() -> Bool {
        return false
    }
}

Verrouiller sur spécifique Orientation

class ViewController: UIViewController {
    override func supportedInterfaceOrientations() -> Int {
        return Int(UIInterfaceOrientationMask.Landscape.rawValue)
    }
}

En théorie, cela devrait fonctionner pour toutes les hiérarchies de contrôleur de vue complexes, mais j'ai remarqué un problème avec UITabBarController. Pour une raison quelconque, il veut utiliser une valeur d'orientation par défaut. Voir le billet de blog suivant si vous êtes intéressé à apprendre comment contourner certains des problèmes:

Rotation De L'Écran De Verrouillage

89
répondu Korey Hinton 2016-11-21 07:25:59

C'est ce qui a fonctionné pour moi:

Https://developer.apple.com/library//ios/documentation/UIKit/Reference/UIViewController_Class/index.html#//apple_ref/occ/clm/UIViewController/attemptRotationToDeviceOrientation

Appelez-le dans votre méthode viewDidAppear:.

- (void) viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    [UIViewController attemptRotationToDeviceOrientation];
}
22
répondu Vincil Bishop 2015-03-18 16:52:40

J'ai trouvé que si c'est un contrôleur de vue présenté, Vous pouvez remplacer preferredInterfaceOrientationForPresentation

Swift:

override func supportedInterfaceOrientations() -> Int {
  return Int(UIInterfaceOrientationMask.Landscape.rawValue)
}

override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
  return UIInterfaceOrientation.LandscapeLeft
}

override func shouldAutorotate() -> Bool {
  return false
}
20
répondu Zipme 2015-03-18 07:38:40

Cette façon de travailler pour moi dans Swift 2 iOS 8.x:

PS (cette méthode n'a pas besoin de remplacer les fonctions d'orientation comme shouldautorotate sur chaque viewController, juste une méthode sur AppDelegate)

Cochez la case "nécessite plein écran" dans les informations générales de votre projet. entrez la description de l'image ici

Donc, sur AppDelegate.swift crée une variable:

var enableAllOrientation = false

Donc, mettez aussi cette fonction:

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
        if (enableAllOrientation == true){
            return UIInterfaceOrientationMask.All
        }
        return UIInterfaceOrientationMask.Portrait
}

Donc, dans chaque classe dans votre projet, vous pouvez définir cette var en viewWillAppear:

override func viewWillAppear(animated: Bool)
{
        super.viewWillAppear(animated)
        let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
        appDelegate.enableAllOrientation = true
}

Si vous devez faire un choix en fonction du type de périphérique, vous pouvez le faire:

override func viewWillAppear(animated: Bool)
    {
        super.viewWillAppear(animated)
        let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
        switch UIDevice.currentDevice().userInterfaceIdiom {
        case .Phone:
        // It's an iPhone
           print(" - Only portrait mode to iPhone")
           appDelegate.enableAllOrientation = false
        case .Pad:
        // It's an iPad
           print(" - All orientation mode enabled on iPad")
           appDelegate.enableAllOrientation = true
        case .Unspecified:
        // Uh, oh! What could it be?
           appDelegate.enableAllOrientation = false
        }
    }
13
répondu Alessandro Ornano 2016-04-07 09:17:14

Cela devrait fonctionner à partir d'iOS 6 vers le haut, mais je ne l'ai testé que sur iOS 8. Sous-classe UINavigationController et remplacer les méthodes suivantes:

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationLandscapeRight;
}

- (BOOL)shouldAutorotate {
    return NO;
}

Ou demandez au contrôleur de vue visible

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return self.visibleViewController.preferredInterfaceOrientationForPresentation;
}

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

Et implémenter les méthodes là-bas.

9
répondu Mojo66 2015-01-31 15:45:01

Ceci est un retour aux commentaires dans la réponse de Sid Shah , concernant la façon de désactiver les animations en utilisant:

[UIView setAnimationsEnabled:enabled];

Code:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:NO];
    [UIView setAnimationsEnabled:NO];

    // Stackoverflow #26357162 to force orientation
    NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
    [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:NO];
    [UIView setAnimationsEnabled:YES];
}
9
répondu ohho 2017-05-23 12:18:22

Tout d'Abord - c'est une mauvaise idée, en général, quelque chose de mal avec votre application architecture, mais, sh..t happens, si oui, vous pouvez essayer de faire quelque chose comme ci-dessous:

final class OrientationController {

    static private (set) var allowedOrientation:UIInterfaceOrientationMask = [.all]

    // MARK: - Public

    class func lockOrientation(_ orientationIdiom: UIInterfaceOrientationMask) {
        OrientationController.allowedOrientation = [orientationIdiom]
    }

    class func forceLockOrientation(_ orientation: UIInterfaceOrientation) {
        var mask:UIInterfaceOrientationMask = []
        switch orientation {
            case .unknown:
                mask = [.all]
            case .portrait:
                mask = [.portrait]
            case .portraitUpsideDown:
                mask = [.portraitUpsideDown]
            case .landscapeLeft:
                mask = [.landscapeLeft]
            case .landscapeRight:
                mask = [.landscapeRight]
        }

        OrientationController.lockOrientation(mask)

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

Que, dans AppDelegate

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // do stuff
    OrientationController.lockOrientation(.portrait)
    return true
}

// MARK: - Orientation

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

Et chaque fois que vous voulez changer d'orientation, faites comme:

OrientationController.forceLockOrientation(.landscapeRight)

Remarque: parfois, le périphérique peut ne pas être mis à jour à partir d'un tel appel, vous devrez donc faire comme suit

OrientationController.forceLockOrientation(.portrait)
OrientationController.forceLockOrientation(.landscapeRight)

C'est tout

7
répondu gbk 2018-02-06 10:16:24

Sur Xcode 8 les méthodes sont converties en Propriétés, ce qui suit fonctionne avec Swift:

override public var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.portrait
}

override public var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation {
    return UIInterfaceOrientation.portrait
}

override public var shouldAutorotate: Bool {
    return true
}
6
répondu Ali Momen Sani 2016-09-21 12:49:30

Si vous utilisez navigationViewController, vous devez créer votre propre superclasse pour cela et remplacer:

- (BOOL)shouldAutorotate {
  id currentViewController = self.topViewController;

  if ([currentViewController isKindOfClass:[SecondViewController class]])
    return NO;

  return YES;
}

Cela va désactiver la rotation dans SecondViewController, mais si vous poussez votre SecondViewController lorsque votre appareil est en mode portrait alors votre SecondViewController apparaît en mode portrait.

Supposons que vous utilisez storyboard. Vous devez créer une séquence manuelle (Comment) et dans votre " onClick" méthode:

- (IBAction)onPlayButtonClicked:(UIBarButtonItem *)sender {
  NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
  [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
  [self performSegueWithIdentifier:@"PushPlayerViewController" sender:self];
}

Cela forcera l'orientation paysage avant que votre superclasse ne désactive la fonction autorotate.

5
répondu Lau 2017-05-23 12:18:22

J'ai essayé de nombreuses solutions, mais celle qui a fonctionné est la suivante:

Il n'est pas nécessaire de modifier le info.plist dans ios 8 et 9.

- (BOOL) shouldAutorotate {
    return NO;
}   

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return (UIInterfaceOrientationPortrait | UIInterfaceOrientationPortraitUpsideDown);
}

Orientations possibles de la Documentation Apple :

UIInterfaceOrientationUnknown

L'orientation du dispositif ne peut pas être déterminée.

UIInterfaceOrientationPortrait

L'appareil est en mode portrait, l'appareil étant maintenu droit et le bouton home sur le fond.

UIInterfaceOrientationPortraitUpsidedown

L'appareil est en mode portrait, mais à l'envers, avec l'appareil tenu debout et le bouton accueil en haut.

UIInterfaceOrientationLandscapeLeft

L'appareil est en mode paysage, l'appareil étant maintenu droit et le bouton d'accueil sur le côté gauche.

UIInterfaceOrientationLandscapeRight

L'appareil est en mode paysage, avec l'appareil tenu debout et le bouton home sur le côté droit.

4
répondu hoogw 2017-08-22 14:18:58

La combinaison des réponses Sids et Koreys a fonctionné pour moi.

Extension du contrôleur de Navigation:

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

Puis désactiver la rotation sur la vue unique

class ViewController: UIViewController {
    override func shouldAutorotate() -> Bool {
        return false
    }
}

Et la rotation à l'orientation appropriée avant le segment

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if (segue.identifier == "SomeSegue")
    {
        let value = UIInterfaceOrientation.Portrait.rawValue;
        UIDevice.currentDevice().setValue(value, forKey: "orientation")
    }
}
3
répondu Misha 2015-03-02 17:59:49

La solution supérieure ci-dessus:

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

N'a pas fonctionné pour moi quand je l'ai appelé dans viewDidAppear du contrôleur de vue présenté. Cependant, cela a fonctionné quand je l'ai appelé dans preparForSegue dans le contrôleur de vue de présentation.

(Désolé, pas assez de points de réputation pour commenter cette solution, donc j'ai dû l'ajouter comme ceci)

2
répondu guido 2015-05-07 21:59:20

Mes exigences sont

  1. verrouille toutes les vues en mode portrait
  2. utiliser AVPlayerViewController pour lire la vidéo

Lorsque la vidéo est en cours de lecture, s'il s'agit d'un paysage, autorisez l'écran à faire pivoter paysage à droite et paysage à gauche. S'il s'agit d'un portrait, verrouillez la vue en mode portrait uniquement.

Tout d'Abord, définissez supportedInterfaceOrientationsForWindow dans AppDelegate.swift

var portrait = true
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
    if portrait {
        return .Portrait
    } else {
        return .Landscape
    }
}

Deuxièmement, dans votre contrôleur de vue principal, définissez les fonctions suivantes

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    print("\(#function)")
    return .Portrait
}

override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
    return .Portrait
}

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

Ensuite, vous devez sous-classer AVPlayerViewController

class MyPlayerViewController: AVPlayerViewController {

    var size: CGSize?

    var supportedOrientationMask: UIInterfaceOrientationMask?
    var preferredOrientation: UIInterfaceOrientation?

    override func viewDidLoad() {
        super.viewDidLoad()

        if let size = size {
            if size.width > size.height {
                self.supportedOrientationMask =[.LandscapeLeft,.LandscapeRight]
                self.preferredOrientation =.LandscapeRight
            } else {
                self.supportedOrientationMask =.Portrait
                self.preferredOrientation =.Portrait
            }
        }
    }

Remplacer ces trois fonctions dans MyPlayerViewController.swift

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return self.supportedOrientationMask!
}

override func preferredInterfaceOrientationForPresentation() -> UIInterfaceOrientation {
    return self.preferredOrientation!
}

Étant donné que l'utilisateur peut faire pivoter le paysage de l'appareil à gauche ou à droite, nous devons définir la rotation automatique pour qu'elle soit vraie

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

Enfin, créez une instance MyPlayerViewController dans votre contrôleur de vue et définissez la valeur de la taille de la propriété.

let playerViewController = MyPlayerViewController()

// Get the thumbnail  
let thumbnail = MyAlbumFileManager.sharedManager().getThumbnailFromMyVideoMedia(......)

let size = thumbnail?.size
playerViewController.size = size

Initiez votre lecteur avec videoUrl approprié, puis affectez votre lecteur à playerViewController. Amusez-vous bien!

2
répondu charles.cc.hsu 2017-08-22 14:14:54
- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [UIViewController attemptRotationToDeviceOrientation];
}
2
répondu Roman Solodyashkin 2017-09-20 11:04:27

Selon la réponse de Korey Hinton

Swift 2.2:

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


extension UITabBarController {
    public override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
        if let selected = selectedViewController {
            return selected.supportedInterfaceOrientations()
        }
        return super.supportedInterfaceOrientations()
    }
    public override func shouldAutorotate() -> Bool {
        if let selected = selectedViewController {
            return selected.shouldAutorotate()
        }
        return super.shouldAutorotate()
    }
}

Désactiver La Rotation

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

Verrouiller à une Orientation spécifique

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.Portrait
}
1
répondu phnmnn 2017-08-22 14:16:40

J'ai essayé quelques solutions ici et la chose importante à comprendre est que c'est le contrôleur de vue racine qui déterminera s'il va tourner ou non.

J'ai créé ce qui suit objective-C project github.com/GabLeRoux/RotationLockInTabbedViewChild avec un exemple fonctionnel de TabbedViewController où une vue enfant est autorisée à tourner et l'autre vue enfant est verrouillée dans portrait.

Ce n'est pas parfait mais cela fonctionne et la même idée devrait fonctionner pour d'autres types de vues racine telles que NavigationViewController. :)

La vue enfant verrouille l'orientation parent

1
répondu GabLeRoux 2017-09-01 11:35:04

[iOS9+] Si quelqu'un traînait tout le chemin ici car aucune des solutions ci dessus n'a fonctionné, et si vous présentez la vue vous voulez changer d'orientation par segue, vous pourriez vouloir vérifier ceci.

Vérifiez le type de présentation de votre segue. Le mien était "sur le contexte actuel". Quand je l'ai changé en plein écran, cela a fonctionné.

Grâce à @GabLeRoux, j'ai trouvé cette solution.

  • ce changement ne fonctionne que lorsqu'il est combiné avec des solutions ci-dessus.
1
répondu Goh 2017-09-27 10:20:17

Selon la solution montrée par @sid-sha, vous devez tout mettre dans la méthode viewDidAppear:, sinon vous n'obtiendrez pas le didRotateFromInterfaceOrientation: tiré, donc quelque chose comme:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    UIInterfaceOrientation interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
    if (interfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
        interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
        NSNumber *value = [NSNumber numberWithInt:interfaceOrientation];
        [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
    }
}
0
répondu loretoparisi 2015-09-30 15:01:45

Ma solution

Dans AppDelegate:

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> UIInterfaceOrientationMask {
    if let topController = UIViewController.topMostViewController() {
        if topController is XXViewController {
            return [.Portrait, .LandscapeLeft]
        }
    }
    return [.Portrait]
}

XXViewController est le ViewController que vous souhaitez prendre en charge le mode paysage.

Alors la solution de Sunny Shah fonctionnerait dans votre XXViewController sur n'importe quelle version d'iOS:

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

C'est la fonction utilitaire pour trouver le plus haut ViewController.

extension UIViewController {

    /// Returns the current application's top most view controller.
    public class func topMostViewController() -> UIViewController? {
        let rootViewController = UIApplication.sharedApplication().windows.first?.rootViewController
        return self.topMostViewControllerOfViewController(rootViewController)
    }



    /// Returns the top most view controller from given view controller's stack.
    class func topMostViewControllerOfViewController(viewController: UIViewController?) -> UIViewController? {
        // UITabBarController
        if let tabBarController = viewController as? UITabBarController,
           let selectedViewController = tabBarController.selectedViewController {
            return self.topMostViewControllerOfViewController(selectedViewController)
        }

        // UINavigationController
        if let navigationController = viewController as? UINavigationController,
           let visibleViewController = navigationController.visibleViewController {
            return self.topMostViewControllerOfViewController(visibleViewController)
        }

        // presented view controller
        if let presentedViewController = viewController?.presentedViewController {
            return self.topMostViewControllerOfViewController(presentedViewController)
        }

        // child view controller
        for subview in viewController?.view?.subviews ?? [] {
            if let childViewController = subview.nextResponder() as? UIViewController {
                return self.topMostViewControllerOfViewController(childViewController)
            }
        }

        return viewController
    }

}
0
répondu duan 2017-05-23 12:02:46

Utilisez ceci pour verrouiller l'orientation du contrôleur de vue, testé sur IOS 9:

/ / verrouiller l'orientation vers la droite du paysage

-(UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscapeRight;
}

-(NSUInteger)navigationControllerSupportedInterfaceOrientations:(UINavigationController *)navigationController {
    return UIInterfaceOrientationMaskLandscapeRight;
}
0
répondu robegamesios 2016-10-18 05:57:07

Il semble encore y avoir un débat sur la meilleure façon d'accomplir cette tâche, alors j'ai pensé partager mon approche (de travail). Ajoutez le code suivant dans votre implémentation UIViewController:

- (void) viewWillAppear:(BOOL)animated
{
    [UIViewController attemptRotationToDeviceOrientation];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
    return (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}

-(BOOL)shouldAutorotate
{
    return NO;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskLandscapeLeft;
}

Pour cet exemple, vous devrez également définir les orientations de votre périphérique autorisé sur 'Paysage gauche' dans les paramètres de votre projet (ou directement dans info.plist). Changez simplement l'orientation spécifique que vous voulez forcer si vous voulez autre chose que LandscapeLeft.

La clé pour moi était l'appel attemptRotationToDeviceOrientation dans viewWillAppear - sans cela, la vue ne tournerait pas correctement sans faire tourner physiquement l'appareil.

0
répondu ViperMav 2017-02-13 02:22:13

J'ai le même problème et je perds tellement de temps pour ça. Alors maintenant j'ai ma solution. Mon paramètre d'application est juste support portrait seulement.Cependant, certains écrans dans mon application ont besoin de paysage seulement.Je le fixer par la variable isShouldRotate à AppDelegate. Et la fonction à AppDelegate:

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> Int {
    if isShouldRotate == true {
        return Int(UIInterfaceOrientationMask.Landscape.rawValue)
    }
    return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}

Et enfin quand un ViewControllerA besoin d'état de paysage. Fais ça: avant poussée / présent pour ViewControllerA affecter isShouldRotate à true. N'oubliez pas que le pop/rejeter assignation isShouldRotate à false à viewWillDisappear.

0
répondu lee 2017-08-22 14:17:26

Pour moi, le VC de niveau supérieur nécessaire pour implémenter les remplacements d'orientation. L'utilisation de VC dans la pile n'aura aucun effet si le VC supérieur n'est pas implémenté.

VC-main
    |
    -> VC 2
        |
        -> VC 3

Seul VC-Main est écouté, essentiellement dans mes tests.

0
répondu bduhbya 2018-01-26 19:37:13