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 ?
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.
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
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
méthodes ajoutées à L'application UIApplication concernant L'Orientation dans iOS6
essayez ceci:
#import <objc/message.h>
if(UIDeviceOrientationIsLandscape(self.interfaceOrientation)){
if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)])
{
objc_msgSend([UIDevice currentDevice], @selector(setOrientation:), UIInterfaceOrientationPortrait );
}
}
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];
}
ce code est pour iOS 8 ou plus tard
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];
essayez ça...ça a marché pour moi...
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
UIView *view = [window.subviews objectAtIndex:0];
[view removeFromSuperview]; [window addSubview:view];
@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;
}
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];
}
}
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).
Apple a rendu la modification de l'orientation de l'appareil programmatique dans iOS6 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)];
}
if (self.interfaceOrientation != UIInterfaceOrientationLandscapeRight) {
// /q/is-there-a-documented-way-to-set-the-iphone-orientation-61797/"setOrientation:") withObject:(id)UIInterfaceOrientationLandscapeRight];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return NO;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return interfaceOrientation == UIInterfaceOrientationPortrait
|| interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown ;
}
cela fonctionne pour moi sur Xcode 6 & 5.
- (BOOL)shouldAutorotate {return YES;}
- (NSUInteger)supportedInterfaceOrientations {return (UIInterfaceOrientationMaskPortrait);}