Dans iOS 5 , nous pourrions modifier l’orientation de l’appareil par programme, comme suit:
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
Mais dans iOS 6 setOrientation
est obsolète, comment puis-je modifier l'orientation de l'appareil par programme dans iOS 6 ?
Voici mes "cinq centimes" testés sur iOS7 avec ARC
[[UIDevice currentDevice] setValue:
[NSNumber numberWithInteger: UIInterfaceOrientationPortrait]
forKey:@"orientation"];
Cela ne génère pas d'avertissement de "fuite" comme le ferait PerformSelector.
UIAlertView - avec ce code, lorsque vous ouvrez UIAlertView pendant une vue (apparaissant/apparaissant), vous remarquerez que tout sauf cette vue est en portrait (Apple, vraiment?) Je n'ai pas réussi à forcer la vue à se réorienter mais vous avez constaté que si vous mettez un léger délai avant d’ouvrir UIAlertView, la vue a le temps de changer d’orientation.
Remarque Je publie ma semaine d'applications à partir du 12/09/2014 et je mettrai à jour le post s'il réussit ou échoue.
Cela ne vous indique pas comment modifier l'orientation du périphérique, mais une information supplémentaire susceptible de vous aider.
iOS 6 Orientation de l'interface utilisateur - shouldAutorotateToInterfaceOrientation: Ne fonctionne pas
La méthode shouldAutorotateToInterfaceOrientation}: N'EST PAS prise en charge par iOS 6. Son obsolète. Juste au cas où vous êtes un débutant qui commence à travailler dans le cacao et se demande pourquoi votre contrôleur de vue est gâché dans iOS 6 et parfait dans iOS 5, sachez simplement que shouldAutorotateToInterfaceOrientation: n'est plus supporté. Même si cela fonctionne bien avec Xcode 4 à 4.3, cela ne fonctionnera PAS sur Xcode 4.5.
Apple fournit une nouvelle méthode pour résoudre ce problème, de manière beaucoup plus propre. Vous utilisez plutôt supportedInterfaceOrientations. Il renvoie toutes les orientations d'interface prises en charge par le contrôleur de vue, ainsi qu'un masque de valeurs d'orientation d'interface.
UIInterfaceOrientationMask Enum:
Ces constantes sont des bits de masque permettant de spécifier les orientations d’interface prises en charge 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;
Utilisation de shouldAutorotateToInterfaceOrientation: method:
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return UIInterfaceOrientationIsLandscapeRight(toInterfaceOrientation);
}
Utilisation de la méthode supportedInterfaceOrientations:
-(NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscapeRight;
}
Ce sont les méthodes ajoutées à UIViewController concernant l'orientation dans iOS6}
Ajout de méthodes à UIApplication concernant l'orientation dans iOS6
J'ai découvert que le moyen le plus simple de forcer le périphérique à modifier l'orientation est de présenter un nouveau contrôleur de vue (à l'aide de presentViewController:animated:completion:
), le nouveau contrôleur de vue spécifiant une orientation préférée particulière (en implémentant la méthode -(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
).
Lorsqu'un nouveau contrôleur de vue est présenté, comme prévu, l'orientation changera pour celle préférée par le nouveau contrôleur de vue. Ainsi, la mise en œuvre la plus simple (meilleure pratique?) Consistera à incorporer toutes les fonctionnalités dont vous avez besoin dans une orientation spécifique dans un contrôleur de vue séparé et à les présenter selon vos besoins. Le système se chargera 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 périphérique à changer d'orientation pour le contrôleur de vue existant.
L'astuce consiste à présenter un nouveau contrôleur de vue avec l'orientation préférée spécifique dont vous aviez besoin, puis à le masquer immédiatement. Cela entraînera une modification temporaire de l'orientation lorsque le nouveau contrôleur de vue est présenté. La meilleure partie est que, lorsque le nouveau contrôleur de vue est congédié, la variable preferredInterfaceOrientationForPresentation
du contrôleur de vue d'origine (présentant) est interrogée à nouveau, vous pouvez spécifier l'orientation finale que vous souhaitez ici.
Une chose importante à regarder ici est de désactiver temporairement la rotation automatique dans le contrôleur de vue original (lorsque vous revenez du contrôleur de vue nouvellement présenté puis rejeté), afin que l'utilisateur ne fasse pas pivoter son téléphone dans la nouvelle orientation, déclenché une autre rotation automatique.
Le code suivant devrait illustrer mon propos, mon exemple force la rotation à portrait, changez simplement en conséquence si vous voulez une autre orientation.
En supposant que vous ayez 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
Essaye ça:
#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 AppDelegate didFinishLaunchingWithOptions
.
Ensuite, n'importe où dans votre application, vous pouvez obtenir l'orientation actuelle avec:
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
Et testez l'orientation avec:
UIInterfaceOrientationIsPortrait(orientation)
UIInterfaceOrientationIsLandscape(orientation)
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 version ultérieure
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];
Une petite modification à la réponse de Bissy, si vous voulez éviter d'utiliser Runtime Library:
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];
}
}
Essayez ceci ... Cela a fonctionné pour moi ...
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
UIView *view = [window.subviews objectAtIndex:0];
[view removeFromSuperview]; [window addSubview:view];
Apple a rendu très difficile le changement de l'orientation de l'appareil par programme dans ios6 (vous le faites exprès).
Autant que je sache, le seul moyen d'accomplir ce que vous demandez est de simuler le changement d'orientation de l'appareil.
Utiliser setTransform
pour faire pivoter la UIView
et réappliquer son propre cadre donne les résultats souhaités.
[YourView setTransform:CGAffineTransformMakeRotation(1.57)];
[YourView setFrame:CGRectMake(0, 0, YourView.frame.size.width, YourView.frame.size.height)];
Et lorsque l'orientation physique du périphérique change, 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)];
}
Cela fonctionne pour iOS7, force autorotate à 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é par Apple.
@implementation UINavigationController (autorotation)
-(NSUInteger)supportedInterfaceOrientations
{
//make the check for iphone/ipad here
if(IPHONE)
{
return UIInterfaceOrientationMaskPortrait;
}
else
{
return UIInterfaceOrientationMaskLandscape;
}
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
- (BOOL)shouldAutorotate
{
return NO;
}
if (self.interfaceOrientation != UIInterfaceOrientationLandscapeRight) {
// http://stackoverflow.com/questions/181780/is-there-a-documented-way-to-set-the-iphone-orientation
// http://openradar.appspot.com/radar?id=697
// [[UIDevice currentDevice] setOrientation: UIInterfaceOrientationLandscapeRight]; // Using the following code to get around Apple's static analysis...
[[UIDevice currentDevice] performSelector:NSSelectorFromString(@"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);}