Comment modifier l'orientation de l'appareil de façon programmatique dans iOS 6

dans iOS 5 nous pourrions modifier l'orientation du dispositif de manière programmatique comme suit:

[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];

mais dans iOS 6 setOrientation est déprécié, Comment puis-je changer l'orientation du dispositif programmatiquement dans iOS 6 ?

42
demandé sur Ricardo Sanchez-Saez 2012-09-29 09:14:28

14 réponses

Voici mes "five cents", testé sur iOS7 avec ARC

[[UIDevice currentDevice] setValue:
                      [NSNumber numberWithInteger: UIInterfaceOrientationPortrait]
                            forKey:@"orientation"];

cela ne génère pas d'avertissement de" fuite " comme performSelector le fera.

UIAlertView - avec ce code, lorsque vous ouvrez UIAlertView pendant la vue (will/Did)apparaître, vous remarquerez que tout sauf cette vue est en portrait (apple, vraiment?) Je n'ai pas été en mesure de forcer la vue à se réorienter mais j'ai constaté que si vous mettez un léger retard avant d'ouvrir la vue UIAlertView puis la vue a le temps de changer d'orientation.

Note je lance mon app week à partir du 12/09/2014 et je mettrai à jour le post si elle passe ou échoue.

46
répondu Lukasz 'Severiaan' Grela 2014-09-10 08:54:25

j'ai découvert que la façon la plus facile de forcer le dispositif à changer l'orientation est de présenter un nouveau contrôleur de vue (en utilisant presentViewController:animated:completion: ) où le nouveau contrôleur de vue a spécifié une orientation préférée particulière (en mettant en œuvre la méthode -(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation ).

Lorsqu'un nouveau contrôleur de vue est présenté, comme prévu, l'orientation va changer vers celui préféré par le nouveau contrôleur de vue. La mise en œuvre la plus simple (meilleure pratique?) sera d'intégrer tous les la fonctionnalité dont vous avez besoin dans une orientation spécifique dans un contrôleur de vue séparé, et la présenter comme nécessaire. Le système prendra soin de changer l'orientation pour vous.

évidemment cela pourrait ne pas convenir à tous les cas d'utilisation, mais, heureusement la même astuce est applicable pour forcer le dispositif à changer l'orientation pour le contrôleur de vue existant.

le truc est de présenter un nouveau contrôleur de vue avec l'orientation préférée spécifique dont vous aviez besoin, et puis le cacher immédiatement. Cela provoquera un changement d'orientation temporaire lorsque le nouveau contrôleur de vue sera présenté. La meilleure partie est que, lorsque le nouveau contrôleur de vue est rejeté, le preferredInterfaceOrientationForPresentation du contrôleur de vue original (presenting) est de nouveau demandé, Vous pouvez spécifier l'orientation finale que vous voulez ici.

Une chose importante à regarder ici est aussi temporaire de désactiver la rotation automatique de l'affichage d'origine contrôleur (revenant de la nouvelle presented-then-dismissed view controller), de sorte que lorsque l'utilisateur tourne son téléphone vers la nouvelle orientation, il ne déclenche pas auto rotation supplémentaire.

le code suivant devrait illustrer mon point, mon exemple forces rotation à portrait, il suffit de changer en conséquence si vous voulez une autre orientation.

en supposant que vous avez le contrôleur de vue d'origine nommé Original , et un contrôleur de vue temporaire nommé ForcePortrait

@interface Original : UIViewController
{
    BOOL orientationToPortrait; //should set to NO by default
}
@end

@implementation Original
- (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation
{
    if(orientationToPortrait)
    {
        //when we manually changed, show in Portrait
        return UIInterfaceOrientationPortrait;
    }
    else
    {
        //before manual orientation change, we allow any orientation
        return self.interfaceOrientation;
    }
}

-(BOOL) shouldAutorotate
{
    //we should 'lock' the rotation once we manually change it
    return !orientationToPortrait;
}

-(void) changeOrientationToPortrait
{
    //Sample method to change the orientation
    //when called, will show (and hide) the temporary view
    //Original.preferredInterfaceOrientationForPresentation will be called again after this method

    //flag this to ensure that we tell system we prefer Portrait, whenever it asked again
    orientationToPortrait = YES;

    //presenting the following VC will cause the orientation to temporary change
    //when the new VC is dismissed, system will ask what is our (Original) orientation preference again
    ForcePortrait* forcePortrait = [[ForcePortrait alloc] init];
    [self presentViewController:forcePortrait animated:NO completion:^{
        [forcePortrait dismissViewControllerAnimated:NO completion:nil];
    }];
}


@end

@interface ForcePortrait : UIViewController
@end

@implementation ForcePortrait
- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationPortrait;
}
@end
20
répondu P.L. 2013-01-03 11:01:05

ceci ne répond pas comment changer l'Orientation de l'appareil, mais une information supplémentaire qui pourrait vous aider.

iOS 6 UI Interface Orientation - shouldautorotetointerfaceorientation : pas de travail

the method shouldautorotetointerfaceorientation : is NOT supported in iOS 6. Ses obsolète. Juste au cas où si vous êtes un débutant, qui vient de regarder travailler dans cocoa, et en se demandant Pourquoi votre contrôleur de vue est foiré dans iOS 6 et parfait dans iOS 5, juste savoir que shouldAutorotateToInterfaceOrientation : n'est plus supporté. Bien qu'il puisse bien fonctionner avec Xcode 4 à 4.3, il ne fonctionnera pas sur Xcode 4.5.

Apple fournit une nouvelle méthode pour obtenir cette chose fait, d'une manière beaucoup plus propre. Vous utilisez supported interfaceorientations à la place. Elle retourne tous les des orientations de l'interface que le contrôleur de vue supporte, un masque des valeurs d'orientation de l'interface.

UIInterfaceOrientationMask Enum:

ces constantes sont des bits de masque pour spécifier les orientations d'interface supportées par un contrôleur de vue.

typedef enum {
    UIInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait),
    UIInterfaceOrientationMaskLandscapeLeft = (1 << UIInterfaceOrientationLandscapeLeft),
    UIInterfaceOrientationMaskLandscapeRight = (1 << UIInterfaceOrientationLandscapeRight),
    UIInterfaceOrientationMaskPortraitUpsideDown = (1 << UIInterfaceOrientationPortraitUpsideDown),
    UIInterfaceOrientationMaskLandscape =
        (UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight),
    UIInterfaceOrientationMaskAll =
        (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft |
    UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortraitUpsideDown),
    UIInterfaceOrientationMaskAllButUpsideDown =
        (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft |
    UIInterfaceOrientationMaskLandscapeRight),
} UIInterfaceOrientationMask;

utilisant shouldautorotetointerfaceorientation: méthode:

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

Utilisation de la méthode d'interfaceorientations supportées:

-(NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskLandscapeRight;
}

ce sont les méthodes ajoutées à UIViewController concernant L'Orientation dans iOS6

  1. UIViewController Preferred interfaceorientation forpresentation

  2. UIViewController shouldAutorotate

  3. UIViewController supportedInterfaceOrientations

méthodes ajoutées à L'application UIApplication concernant L'Orientation dans iOS6

  1. UIApplication a soutenu desinterfacesorientationspour la formule:

  2. UIInterfaceOrientationMask

19
répondu Bala 2014-12-27 07:08:43

essayez ceci:

#import <objc/message.h>

if(UIDeviceOrientationIsLandscape(self.interfaceOrientation)){
        if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)])
        {
            objc_msgSend([UIDevice currentDevice], @selector(setOrientation:), UIInterfaceOrientationPortrait );
        }
    }
10
répondu Bissy 2012-10-09 14:01:35

vous devriez placer

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

dans votre méthode didFinishLaunchingWithOptions .

alors, n'importe où dans votre application vous pouvez obtenir l'orientation actuelle avec:

UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];

et orientation de l'essai avec:

UIInterfaceOrientationIsPortrait(orientation) 
UIInterfaceOrientationIsLandscape(orientation)

comme, comme

if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation))
{
    // code for landscape orientation
     // OR
    [[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
     //  OR
    [[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeLeft];

}
else if (UIDeviceOrientationIsPortrait([UIDevice currentDevice].orientation))
{
    // code for Portrait orientation
    //  OR
   [[UIDevice currentDevice] setOrientation:UIInterfaceOrientationPortraitUpsideDown];
    //  OR
   [[UIDevice currentDevice] setOrientation:UIInterfaceOrientationPortrait];
}
5
répondu iPatel 2013-09-02 04:37:05

ce code est pour iOS 8 ou plus tard

NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];
4
répondu Raul Quispe 2015-10-24 03:36:44

essayez ça...ça a marché pour moi...

UIWindow *window = [[UIApplication sharedApplication] keyWindow];
UIView *view = [window.subviews objectAtIndex:0];
[view removeFromSuperview]; [window addSubview:view];
2
répondu Hiren Patel 2012-10-30 12:02:49

@mise en œuvre UINavigationController (rotation automatique)

 -(NSUInteger)supportedInterfaceOrientations
 {
   //make the check for iphone/ipad here

    if(IPHONE)
    {
      return UIInterfaceOrientationMaskPortrait;
    } 
    else
    {
      return UIInterfaceOrientationMaskLandscape;
    }
 }

 - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
 {
    return UIInterfaceOrientationPortrait;
 }

 - (BOOL)shouldAutorotate
 {
    return NO;
 }
2
répondu Shauket Sheikh 2013-11-07 04:32:54

une petite modification à la réponse de Bissy, si vous voulez éviter d'utiliser la bibliothèque Runtime:

if (UIDeviceOrientationIsLandscape([[UIDevice currentDevice] orientation]))
{
    if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)])
    {
        int orientationPortrait = UIInterfaceOrientationPortrait;
        NSMethodSignature *sig = [[UIDevice currentDevice] methodSignatureForSelector:@selector(setOrientation:)];
        NSInvocation* invo = [NSInvocation invocationWithMethodSignature:sig];
        [invo setTarget:[UIDevice currentDevice]];
        [invo setSelector:@selector(setOrientation:)];
        [invo setArgument:&orientationPortrait atIndex:2];
        [invo invoke];
    }
}
2
répondu Perisheroy 2013-11-19 23:36:46

cela fonctionne pour iOS7, autorotate de force à portrait.

//In your viewController.m
#import <objc/message.h>

// for autorotate viewController to portraid
- (void)viewWillAppear:(BOOL)animated {
    UIInterfaceOrientation orientationStatusBar =[[UIApplication sharedApplication] statusBarOrientation];
    switch (orientationStatusBar) {
        case UIInterfaceOrientationPortrait:break;
        case UIInterfaceOrientationLandscapeLeft:
            objc_msgSend([UIDevice currentDevice], @selector(setOrientation:), UIInterfaceOrientationPortrait);
            break;
        case UIInterfaceOrientationLandscapeRight:
            objc_msgSend([UIDevice currentDevice], @selector(setOrientation:), UIInterfaceOrientationPortrait);
            break;
        default:
            break;
    }
}

// this permit autorotate
- (BOOL) shouldAutorotate
{
   // this lines permit rotate if viewController is not portrait
    UIInterfaceOrientation orientationStatusBar =[[UIApplication sharedApplication] statusBarOrientation];
    if (orientationStatusBar != UIInterfaceOrientationPortrait) {
        return YES;
    }
    //this line not permit rotate is the viewController is portrait
    return NO;
}

NOTE: j'ai implémenté cette option dans mon application, mais je serais probablement rejetée par Apple (commentaire pour Austin pour edited 6 de Sergey K. en octobre 2012).

2
répondu ppVen 2014-11-25 22:09:00

Apple a rendu la modification de l'orientation de l'appareil programmatique dans assez difficile(à propos de vous).

pour autant que je sache, la seule façon d'accomplir ce que vous demandez est de simuler le changement d'orientation de l'appareil.

en utilisant setTransform pour faire tourner le UIView et appliquer de nouveau son propre cadre donne les résultats désirés.

[YourView setTransform:CGAffineTransformMakeRotation(1.57)];
[YourView setFrame:CGRectMake(0, 0, YourView.frame.size.width, YourView.frame.size.height)];

et lorsque le dispositif physique changements d'orientation nous pouvons annuler la transformation.

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [YourView setTransform:CGAffineTransformMakeRotation(0)];
    [YourView setFrame:CGRectMake(0, 0, YourView.frame.size.width, YourView.frame.size.height)];
}
2
répondu Aleksander Azizi 2017-05-19 18:20:41
if (self.interfaceOrientation != UIInterfaceOrientationLandscapeRight) {
// /q/is-there-a-documented-way-to-set-the-iphone-orientation-61797/"setOrientation:") withObject:(id)UIInterfaceOrientationLandscapeRight];
}
1
répondu n00bProgrammer 2013-08-30 08:41:26
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{
    // Return YES for supported orientations
   return NO;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
   return  interfaceOrientation == UIInterfaceOrientationPortrait
           || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown ;
}
0
répondu ganesh 2013-02-22 10:20:55

cela fonctionne pour moi sur Xcode 6 & 5.

- (BOOL)shouldAutorotate {return YES;}
- (NSUInteger)supportedInterfaceOrientations {return (UIInterfaceOrientationMaskPortrait);}
0
répondu SamSmart 2014-10-12 13:47:53