Je souhaite faire pivoter UNIQUEMENT l'une de mes vues dans mon application vers paysage à gauche ou paysage à droite. Toutes mes autres vues sont en mode portrait et j'ai configuré mon application pour prendre en charge uniquement le mode portrait. Avec l'orientation changée dans iOS 6, je ne sais pas comment faire. J'ai essayé ce qui suit posté ci-dessous. Quelqu'un peut-il me dire ce que je fais mal? Merci!
-(BOOL)shouldAutorotate {
return YES;
}
-(NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskLandscapeLeft;
}
J'ai aussi essayé:
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(didRotate:)
name:UIDeviceOrientationDidChangeNotification
object:nil];
return YES;//UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskLandscapeLeft;
}
-(void)didRotate:(NSNotification *)notification {
UIDeviceOrientation orientation = [[notification object] orientation];
if (orientation == UIDeviceOrientationLandscapeLeft) {
[theImage setTransform:CGAffineTransformMakeRotation(M_PI / -2.0)];
[self.view setTransform:CGAffineTransformMakeRotation(M_PI / 2.0)];
} else if (orientation == UIDeviceOrientationLandscapeRight) {
[theImage setTransform:CGAffineTransformMakeRotation(M_PI / -2.0)];
[self.view setTransform:CGAffineTransformMakeRotation(M_PI / -2.0)];
} else if (orientation == UIDeviceOrientationPortraitUpsideDown) {
[theImage setTransform:CGAffineTransformMakeRotation(M_PI / -2.0)];
[self.view setTransform:CGAffineTransformMakeRotation(M_PI / -2.0)];
} else if (orientation == UIDeviceOrientationPortrait) {
[theImage setTransform:CGAffineTransformMakeRotation(M_PI / 2.0)];
[self.view setTransform:CGAffineTransformMakeRotation(M_PI / 2.0)];
}
}
Cela a fonctionné pour moi Comment forcer un UIViewController à l’orientation Portrait dans iOS 6
Créez une nouvelle catégorie à partir de UINavigationController en remplaçant les méthodes de rotation:
-(BOOL)shouldAutorotate
{
return [self.topViewController shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [self.topViewController preferredInterfaceOrientationForPresentation];
}
@end
Il y a des changements dans iOS 6 concernant la gestion des rotations de vues. Seules les orientations définies dans les applications Info.plist
sont prises en charge. Même si vous retournez d'autres.
Essayez de sélectionner toutes les orientations comme supportées dans votre projet.
Gestion des rotations de vues
Dans iOS 6, votre application prend en charge les orientations d’interface définies dans le fichier
Info.plist
de votre application. Un contrôleur de vue peut remplacer la méthodesupportedInterfaceOrientations
pour limiter la liste des orientations prises en charge. Généralement, le système appelle cette méthode uniquement sur le contrôleur de vue racine de la fenêtre ou sur un contrôleur de vue présenté pour remplir la totalité de l'écran. Les contrôleurs de vue enfants utilisent la partie de la fenêtre qui leur est fournie par leur contrôleur de vue parent et ne participent plus directement aux décisions concernant les rotations prises en charge. L’intersection du masque d’orientation de l’application et du masque d’orientation du contrôleur de vue sert à déterminer les orientations dans lesquelles le contrôleur de vue peut être pivoté.Vous pouvez remplacer la
preferredInterfaceOrientationForPresentation
pour un contrôleur de vue destiné à être présenté en plein écran dans une orientation spécifique.Dans iOS 5 et les versions antérieures, la classe
UIViewController
affiche uniquement les vues en mode portrait. Pour prendre en charge d'autres orientations, vous devez remplacer la méthodeshouldAutorotateToInterfaceOrientation:
et renvoyer YES pour toute orientation prise en charge par votre sous-classe. Si les propriétés de redimensionnement automatique de vos vues sont correctement configurées, il vous suffira peut-être de le faire. Cependant, la classeUIViewController
fournit des points d'ancrage supplémentaires pour vous permettre d'implémenter des comportements supplémentaires en fonction des besoins. En règle générale, si votre contrôleur de vue est destiné à être utilisé comme contrôleur de vue enfant, il doit prendre en charge toutes les orientations de l'interface.Lorsqu'une rotation se produit pour un contrôleur de vue visible, les méthodes
willRotateToInterfaceOrientation:duration
:,willAnimateRotationToInterfaceOrientation:duration:
etdidRotateFromInterfaceOrientation:
sont appelées pendant la rotation. La méthodeviewWillLayoutSubviews
est également appelée une fois la vue redimensionnée et positionnée par son parent. Si un contrôleur de vue n'est pas visible lorsqu'un changement d'orientation se produit, les méthodes de rotation ne sont jamais appelées. Cependant, la méthodeviewWillLayoutSubviews
est appelée lorsque la vue devient visible. Votre implémentation de cette méthode peut appeler la méthodestatusBarOrientation
pour déterminer l'orientation du périphérique.
Suivez les étapes ci-dessous
J'ai créé pour cela un exemple de projet qui fonctionne parfaitement. Téléchargez et intégrez dans votre projet: https://www.dropbox.com/s/nl1wicbx52veq41/RotationDmeo.zip?dl=0
J'ai un:
TabbarController -> NavigationController -> ViewController -> ViewController
J'ai sous-classé UITabBarController
et ajouter ....
-(NSUInteger)supportedInterfaceOrientations{
if (self.selectedIndex >= 0 && self.selectedIndex < 100) {
for (id vC in [[self.viewControllers objectAtIndex:(unsigned long)self.selectedIndex] viewControllers]) {
if ([vC isKindOfClass:[CLASS_WHICH_SHOULD_ALLOW class]]) {
return UIInterfaceOrientationMaskPortrait + UIInterfaceOrientationMaskLandscape;
}
}
}
return UIInterfaceOrientationMaskPortrait;
}
Je cherche la solution depuis des heures!
Donc, après avoir mis en œuvre les méthodes nécessaires partout. shouldAutorotate
n'a pas besoin d'être défini sur YES
car il est déjà défini par défaut:
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
return UIInterfaceOrientationPortrait;
}
Lorsqu'il est temps d'afficher la UIViewController
qui nécessite une orientation différente de celle des autres vues, j'ai créé une UIStoryboardSegue
avec cette implémentation à l'intérieur:
#import "Showing.h"
@implementation Showing
- (void)perform{
NSLog(@"Showing");
UIViewController *sourceVC = self.sourceViewController;
UIViewController *presentingVC = self.destinationViewController;
[sourceVC.navigationController presentViewController:presentingVC
animated:YES
completion:nil];
}
@end
À l'intérieur de la UIStoryboard
, j'ai relié les vues à cette séquence (montrant):
C'est juste important, vous utilisez
presentViewController:animated:completion:
ET PAS
pushViewController:animated:
sinon l'orientation ne sera pas déterminée à nouveau .
[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
OU celui-ci à l'intérieur de la UIViewController
où l'orientation devrait changer, et j'ai aussi essayé de l'appeler dans ma coutume UIStoryboardSegues
avant presentingViewController
et dismissViewController
:
[UIViewController attemptRotationToDeviceOrientation];
OU
NSNumber *numPortrait = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:numPortrait forKey:@"orientation"];
Mais aucun d'entre eux n'a travaillé. Bien sûr, le dernier exemple ne devrait pas être une option, car si Apple modifiait quoi que ce soit de son API, cela pourrait poser des problèmes au sein de votre application.
J'ai également essayé d'utiliser la méthode AppDelegate
et de toujours déterminer l'orientation à l'intérieur de cette méthode après avoir recherché la bonne UIInterfaceOrientation
de la visibleViewController
réelle, mais il arrivait parfois qu'il y ait un blocage lors du passage d'une orientation à une autre. Je me demande donc toujours pourquoi cela est si compliqué et qu'il semble également ne pas y avoir de documentation où elle est expliquée correctement ... Même après cette partie ne m'a pas aidé moi.
UIViewController + OrientationPermissions.h
@interface UIViewController (OrientationPermissions)
+ (void)setSupportedOrientations:(UIInterfaceOrientationMask)supportedOrientations;
+ (UIInterfaceOrientationMask)supportedOrientations;
@end
UIViewController + OrientationPermissions.m
@implementation UIViewController (OrientationPermissions)
static UIInterfaceOrientationMask _supportedOrientations;
+ (void)setSupportedOrientations: (UIInterfaceOrientationMask)supportedOrientations {
_supportedOrientations = supportedOrientations;
}
+ (UIInterfaceOrientationMask)supportedOrientations {
return _supportedOrientations;
}
@end
Dans votre délégué UIApplication
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
return [UIViewController supportedOrientations];
}
Ensuite, sur un contrôleur de vue souhaité, faites quelque chose comme
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[UIViewController setSupportedOrientations:UIInterfaceOrientationMaskAll];
}
N'oubliez pas de réinitialiser le masque avant de quitter ce contrôleur de vue
Notez que si vous utilisez UINavigationController ou UITabBarController, voir https://stackoverflow.com/a/28220616/821994 comment contourner ce problème