FAQ et Solutions pour iPhone Landscape

il y a eu beaucoup de confusion et un ensemble de questions correspondantes ici sur la façon dont les applications iPhone avec une manipulation appropriée pour l'autorotation en mode Paysage/Portrait peuvent être mises en œuvre. Il est particulièrement difficile de mettre en œuvre une telle application lorsque l'on souhaite commencer en mode paysage. L'effet observé le plus fréquent est la mise en page brouillée et les zones de l'écran où les touches ne sont plus reconnues.

une simple recherche de questions marquées iphone et landscape révèle ces questions, qui se produisent dans certains scénarios:

un ensemble de différentes solutions ont été présentées, certaines incluant une animation entièrement personnalisée via Corégraphie, tandis que d'autres s'appuient sur l'observation que le contrôleur de première vue chargé à partir de la portée principale est toujours affiché correctement.

j'ai passé beaucoup de temps à étudier cette question et j'ai finalement trouvé une solution qui n'est pas seulement une solution partielle mais qui devrait fonctionner dans toutes ces circonstances. J'ai l'intention avec ce post de CW de fournir une sorte de FAQ pour les autres ayant des problèmes avec UIViewControllers en mode paysage.

s'il vous Plaît fournir une rétroaction et d'aider à améliorer la qualité de ce Post, en intégrant toutes les observations relatives. N'hésitez pas à éditer et à poster d'autres/meilleures réponses si vous en connaissez.

18
demandé sur Johannes Rudolph 2010-06-02 01:08:27

6 réponses

Ce qui est dans le documentation :

dans votre contrôleur de vue, override shouldautorotetetointerfaceorientation: pour déclarer les orientations de votre interface supportée. Cette propriété sera/devrait être vérifiée par l'infrastructure du contrôleur chaque fois que l'orientation du périphérique change.

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation
{
   return  (orientation == UIInterfaceOrientationLandscapeRight);
}

C'est le minimum absolu que votre contrôleur de vue doit faire. Si vous souhaitez lancer votre application dans landscape mode, vous devez ajouter la clé suivante à votre .plist fichier:

<key>UIInterfaceOrientation</key>
<string>UIInterfaceOrientationLandscapeRight</string>

Apple recommande de lancer les applications landscape only en mode Landscape Right (voir the HIG sous la rubrique User Experience Guidelines > Start Instantly).

ce qui n'est pas dans la documentation:

un petit fond:

chaque fois que vous essayez de charger un contrôleur de vue différent autre que celui chargé à partir du nib principal, votre contrôleur de vue n'est pas interrogé sur les orientations de l'interface qu'il supporte et son cadre n'est pas correctement paramétré. Seul le contrôleur de première vue relié à la fenêtre sera affiché correctement.

D'autres personnes ont suggéré d'utiliser un" MasterViewController " relié à la fenêtre principale à laquelle d'autres contrôleurs ajoutent leurs vues comme des sous-vues au lieu de les accrocher directement dans la fenêtre. Bien que j'ai trouvé ces solutions est une option viable, il ne fonctionne pas correctement dans le cas de modal vue contrôleurs ajouté les sous-vues. Il y a aussi un problème si vous avez des sous-vues ou qui devraient être en mesure d'effectuer une autorotation (ce que le contrôleur maître empêchera).

l'utilisation d'API non documentée pour forcer une certaine orientation de l'interface n'est pas une option non plus.

La solution:

la meilleure solution que j'ai trouvée jusqu'à présent est un modification de la solution "MasterViewController". Au lieu d'utiliser un "MasterViewController" personnalisé, un UINavigationController avec barre de Navigation cachée et barre de tabulation cachée est utilisé. Si toutes les autres vues sont repoussées / désactivées de la pile de navigation de ce contrôleur, les auto-rotations des contrôleurs sur cette pile seront gérées correctement.

Modal contrôleurs présentés par le biais de presentModalViewController:animated: à partir de la vue des contrôleurs sur le UINavigationController pile de navigation sera tourné et rendu avec la mise en page correcte. Si vous voulez que votre contrôleur de vue modale tourne vers une orientation différente de celle du contrôleur de vue parent, vous devez retourner l'orientation désirée à partir de la méthode shouldAutorotateToInterfaceOrientation du contrôleur parent pendant que la vue modale est présentée. Afin de restaurer correctement l'orientation de l'interface lorsque le contrôleur modal est rejeté, vous devez vous assurer que shouldAutorotateToInterfaceOrientation renvoie l'orientation désirée pour le parent contrôleur avant d'appeler dismissModalViewController:animated: . Vous pouvez utiliser un BOOL privé sur votre contrôleur de vue pour gérer cela (par exemple BOOL isModalMailControllerActive_ ).

je vais ajouter un morceau de code bientôt, il est juste trop tard maintenant. S'il vous plaît laissez-moi savoir si toutes les questions en suspens restent ou quelque chose n'est pas claire sur ce post. N'hésitez pas à modifier et améliorer.

13
répondu Johannes Rudolph 2012-01-15 13:26:09

j'ai eu une intéressante exigence pour ios de l'application:

vue principale controller ne doit être que paysage, mais tous les autres (qui peuvent être poussés de main) peuvent être paysage et portrait.

problème se produit-quand je pousse à un nouveau viewController, qui est ensuite tourné à dépeindre - et le pop back - vue principale n'est plus Paysage. Aussi-Application d'ouverture, il n'est pas dans le paysage.

afin de garder la vue main controller paysage, peu importe de quelle orientation il a été popped / poussé, j'ai fait la chose suivante: (en viewWillAppear:)

//set statusbar to the desired rotation position
[[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationLandscapeLeft animated:NO];

//present/dismiss viewcontroller in order to activate rotating.
UIViewController *mVC = [[[UIViewController alloc] init] autorelease];
[self presentModalViewController:mVC animated:NO];
[self dismissModalViewControllerAnimated:NO];

J'espère que ça aidera quelqu'un!

P.S. testé sur sdk 3.2.5 ios 5.0.1.

merci pour toutes les infos dans cette FAQ!

7
répondu Guntis Treulands 2012-04-13 18:24:38

pour le second point, si vous voulez utiliser pushViewController pour passer d'une vue Portrait-only à une vue paysage-only, un hack simple que j'ai trouvé est de mettre le code suivant dans le viewDidLoad de votre contrôleur poussé:

UIViewController *viewController = [[UIViewController alloc] init];
[self presentModalViewController:viewController animated:NO];
[self dismissModalViewControllerAnimated:NO];
[viewController release];
3
répondu MyCSharpCorner 2011-10-29 08:53:59

j'aimerais ajouter à la réponse de Johannes (en utilisant le Controller UINavigationController comme MasterViewController).

l'inconvénient que j'ai constaté est que les contrôleurs de vue qui sont nouvellement poussés sur la pile de navigation du maître VC ne s'ajustent pas aux changements d'orientation antérieurs. En bref, les VCs déjà sur la pile sont tournés, les contrôleurs de vue modale présentés à partir d'eux sont également tournés, mais les VCs nouvellement ajoutés sont et non tournés.

J'ai essayé de nombreux trucs pour corriger cela avant de trouver un qui fonctionne. La plupart ne fonctionnent que pour pushViewController: avec le jeu animé à Oui.

pour régler entièrement la question, j'AI sous-classé UINagivationController et remplacé pushViewController:animated: comme suit:

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    // Correctly autoOrient the given view controller
    [self presentModalViewController:viewController animated:NO];
    [self dismissModalViewControllerAnimated:NO];

    // Push it as normal (now in its correct orientation)
    [super pushViewController:viewController animated:animated];
}

Temporairement (et de manière très invisible) la présentation du contrôleur de vue lui permet de recevoir sa mise à jour d'orientation. Il peut ensuite être poussé sur la pile de navigation dans sa bonne orientation.

s'il vous Plaît laissez-moi savoir si cela fonctionne pour vous. Toutes les mises à jour et améliorations sont les bienvenues!

enfin, je recommande fortement L'approche de Johannes à la gestion de la rotation.

EDIT: mise à Jour sur popping vue des contrôleurs de la pile

il semble que tous les sélecteurs liés au popViewController deviennent fous lorsqu'ils sont joués avec animated:YES. Plus précisément, le contrôleur de vue est animé dans le mauvaise direction. Vous pouvez utiliser animated:NO et restreindre l'utilisation de telles animations à d'autres UINavigationControllers situés plus bas dans votre hiérarchie (c'est-à-dire ceux que vous poussez sur la pile du contrôleur de navigation racine).

toute entrée est grandement appréciée.

2
répondu Timo 2011-03-16 16:48:46

je suis en train de développer une application iPad qui affiche une vue de galerie à la verticale d'un tableau d'articles au démarrage. En mode paysage il y a 4 items à travers. En portrait il y en a trois. En tournant l'orientation de l'iPad, il est supposé rafraîchir la galerie pour avoir les éléments s'ajustent parfaitement à travers l'écran. Puis je double appuyez sur un élément pour accéder au modale vue de cet élément. Alors je fais des trucs avec cet objet. Enfin, je rejette la vision modale.

au Cours de le rafraîchissement ou la modification de l'orientation la vue galerie calcule le nombre d'éléments à afficher en fonction de la largeur (ou de la hauteur) de l'écran et de l'orientation actuelle de UIViewController.interfaceOrientation.

j'avais un problème pour que cela fonctionne correctement. Parfois, il n'afficherait que deux éléments dans l'orientation du paysage après que j'ai écarté le Dialogue modal.

au début, j'utilisais le UIViewController.vue.cadre.valeurs de taille pour calculer nombre d'éléments de la galerie. Lorsque la vue modale a été rejetée, cette taille de cadre était incorrecte, par exemple la largeur et la hauteur avaient été inversées, même si l'orientation n'avait pas changé pendant que la boîte de dialogue modale était affichée.

je suis passé à l'utilisation de l'application délégué ([UIApplication sharedApplication] délégué]) et de prendre la fenêtre.cadre.taille pour calculer le nombre d'articles de galerie à afficher à travers. Fenêtre.cadre.la taille reste correcte sous les changements d'orientation et les boîtes de dialogue modales. Les objets de la galerie s'affichent correctement maintenant.

2
répondu Will Marsh 2012-12-12 04:46:20

ça va marcher...

UIWindow *window = [[UIApplication sharedApplication] keyWindow];
    UIView *view = [window.subviews objectAtIndex:0];
    [view removeFromSuperview];
    [window addSubview:view];
-3
répondu Hiren Patel 2012-10-22 11:40:23