48 votes

iOS 6 shouldAutorotate : n'est PAS appelé

J'ai parcouru l'internet pour trouver une solution à ce problème mais je n'ai rien trouvé. J'essaie de rendre mon application iOS 5 compatible avec iOS 6. Je n'arrive pas à faire fonctionner correctement le système d'orientation. Je suis incapable de détecter quand une rotation est sur le point de se produire. Voici le code que j'essaie :

- (BOOL)shouldAutorotate {
    return NO;
}

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}
// pre-iOS 6 support
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    return (toInterfaceOrientation == UIInterfaceOrientationPortrait);
}

La nouvelle méthode supportedInterfaceOrientation : est appelée sans problème. La méthode shouldAutorotate, en revanche, ne se déclenche pas. J'ai besoin de faire des échanges d'images lors de la rotation, mais je n'obtiens aucune indication qu'une rotation est sur le point de se produire.

Merci d'avance.

0 votes

La réponse à cette question se trouve ici : stackoverflow.com/questions/12260261/ Regardez-le :D

0 votes

@KarenAnne, cette réponse ne résout pas le problème de 'shouldAutorotate' qui n'est pas appelé en premier lieu. De plus, "shouldAutorotateToInterfaceOrientation" est déprécié dans iOS 6, il ne devrait donc pas être considéré comme une option valide à l'avenir.

80voto

user1672376 Points 661

Vérifiez si vous obtenez l'erreur suivante lorsque votre application démarre.

Les fenêtres d'application doivent avoir un contrôleur de vue racine à la fin du lancement de l'application.

Si c'est le cas, la solution consiste à apporter la modification suivante au fichier AppDelegate.m (bien qu'il semble y avoir un certain nombre de réponses pour résoudre ce problème) :

// Replace
[self.window addSubview:[navigationController view]];  //OLD

// With
[self.window setRootViewController:navigationController];  //NEW

Après cette shouldAutoRotate devrait être appelé correctement.

1 votes

Je pense que cela devrait être accepté comme la réponse correcte. J'ai eu le même problème auparavant mais j'ai pu le résoudre en faisant quelque chose comme ceci : self.window.rootViewController = navigationController ; (ce qui est la même chose que la réponse de @user1672376)

0 votes

Oui, j'ai essayé de faire en sorte que la méthode shouldAutoRotate soit appelée mais cela ne fonctionnait pas ; dès que j'ai modifié le morceau de code ci-dessus, cela a fonctionné parfaitement. C'est la bonne réponse, je l'ai beaucoup cherchée.

0 votes

Super ça m'a fait gagner du temps ;-)

45voto

Mike Pollard Points 3146

Lorsque j'utilise UINavigationController comme base d'une application, j'utilise la sous-classe suivante pour me donner la flexibilité de permettre au viewcontroller enfant le plus haut de décider de la rotation.

@interface RotationAwareNavigationController : UINavigationController

@end

@implementation RotationAwareNavigationController

-(NSUInteger)supportedInterfaceOrientations {
    UIViewController *top = self.topViewController;
    return top.supportedInterfaceOrientations;
}

-(BOOL)shouldAutorotate {
    UIViewController *top = self.topViewController;
    return [top shouldAutorotate];
}

@end

5 votes

C'est de loin la solution la plus simple et la plus élégante pour permettre à chaque ViewController d'un NavigationController de disposer de ses propres orientations d'interface prises en charge.

0 votes

Il s'agit en effet d'une excellente solution, qui peut également être utilisée avec les SplitViewControllers moyennant quelques modifications.

0 votes

Pour être plus clair, créez une telle sous-classe, puis définissez-la comme classe personnalisée pour votre contrôleur de navigation dans l'inspecteur d'identité du storyboard.

15voto

borrrden Points 20950

Cette méthode n'est pas la bonne façon de le déterminer. La méthode correcte est willRotateToInterfaceOrientation:duration:

La méthode should rotate to orientation (par opposition à shouldAutorotate) est obsolète et ne sera plus appelée à partir d'iOS 6, mais elle n'était pas censée être utilisée de la manière dont vous l'avez utilisée de toute façon.

EDITAR Réponse aux votes négatifs répétés. Veuillez expliquer pourquoi l'utilisation de la méthode que j'ai indiquée n'est pas (pour citer le PO) "une indication qu'une rotation est sur le point de se produire." Le contenu de la question et le titre ne concordent pas.

2 votes

-(BOOL)shouldRotate est apparu dans iOS 6, cependant, il n'est jamais appelé. Comment peut-on avoir un contrôleur de vue qui ne tourne qu'une partie du temps maintenant (par exemple en ayant un bouton de verrouillage pour se protéger des rotations) ?

14 votes

J'ai compris pourquoi mon shouldAutorotate n'était pas appelé dans iOS 6. C'était dû au fait que mon contrôleur de vue était un enfant d'un UINavigationController et il semble que le contrôleur de vue ne délègue pas la méthode -shouldAutorotate à son topViewController comme le comportement précédent. Vous pouvez contourner ce problème en sous-classant le UINavigationController et en surchargeant les méthodes -shouldAutorotate et -supportedIntervalOrientations.

0 votes

Oui, c'est une nouvelle façon de faire les choses... seuls les contrôleurs de vue présentés et Root reçoivent les appels. Le raisonnement est que les contrôleurs de vue enfants se contentent généralement de redimensionner pour s'adapter aux cadres de leurs parents de toute façon. Cependant, les méthodes wilRotate et didRotate sont transmises par défaut aux contrôleurs enfants.

10voto

Adrian Points 786

Il semble que sous iOS 6, le contrôleur de navigation du conteneur ne consulte pas les contrôleurs de vue enfants lors de la rotation :

sur Notes de publication d'iOS 6 :

Désormais, les conteneurs iOS (tels que UINavigationController) ne consultent pas leurs enfants pour déterminer s'ils doivent effectuer une rotation automatique. Par défaut, les orientations d'interface prises en charge par une app et un contrôleur de vue d'une application et d'un contrôleur de vue sont définies sur UIInterfaceOrientationMaskAll pour l'idiome iPad et UIInterfaceOrientationMaskAllButUpsideDown pour l'idiome iPhone pour l'iPhone.

Ce comportement est facile à tester. Ce que j'ai fait est d'utiliser le même contrôleur de vue personnalisé

  1. premier cas comme contrôleur de vue principal
  2. deuxième cas comme enfant d'un UIPageViewController

Dans le premier cas, tout est décidé dans le contrôleur de navigation personnalisé par la combinaison des éléments suivants shouldAutorotate y supportedInterfaceOrientations étant donné que supportedInterfaceOrientations est en accord avec les orientations prises en charge par l'application.

Dans le second cas, même si le supportedInterfaceOrientations du contrôleur de vue personnalisé est appelé par le UIPageViewController, la valeur de retour n'est pas prise en compte. Cela fonctionne si les deux méthodes sont écrasées dans une sous-classe de UIPageViewController. Je ne suis pas sûr des effets secondaires de cette méthode, car cette classe n'est pas censée être sous-classée.

10voto

Basheer_CAD Points 2087

Si votre viewController est un enfant viewController dans un UINavigationController alors vous pouvez faire ce qui suit :

  • Sous-classe UINavigationController
  • contourner shouldAutoRotate dans votre sous-classe
  • envoyez votre topViewController ce message lorsque cette méthode est appelée

// Cette méthode se trouve dans votre UINavigationController sous-classe

- (BOOL)shouldAutorotate
{
    if([self.topViewController respondsToSelector:@selector(shouldAutorotate)])
    {
        return [self.topViewController shouldAutorotate];
    }
    return NO;
}
  • Maintenant, vos viewControllers répondront respectivement à cette méthode.
  • Notez que vous pouvez faire de même avec d'autres méthodes d'orinetaion.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X