web-dev-qa-db-fra.com

Le lancement en orientation portrait à partir d'un écran d'accueil iPhone 6 Plus en orientation paysage entraîne une mauvaise orientation

Le titre réel de cette question est plus long que je ne peux le faire:

Le lancement d'une application dont le contrôleur de vue racine ne prend en charge que l'orientation portrait mais qui prend en charge les orientations paysage sur un iPhone 6 Plus alors que l'écran d'accueil est en orientation paysage entraîne un état limbo où la fenêtre de l'application est en orientation paysage mais l'appareil est en orientation portrait.

En bref, cela ressemble à ceci:

Quand il est censé ressembler à ceci:

Étapes à reproduire:

  1. iPhone 6 Plus sous iOS 8.0.

  2. Une application dont le plist prend en charge les orientations à l'envers, sauf en mode portrait.

  3. Le contrôleur de vue racine de l'application est un UITabBarController.

  4. Tout, le contrôleur de barre d'onglets et tous ses contrôleurs de vue enfant descendants renvoient UIInterfaceOrientationMaskPortrait de supportedInterfaceOrientations.

  5. Commencez sur l'écran d'accueil iOS.

  6. Rotation en orientation paysage (nécessite l'iPhone 6 Plus).

  7. Lancez l'application à froid.

  8. Résultat: orientations d'interface brisées.

Je ne vois pas d'autre moyen d'appliquer une orientation portrait sauf pour désactiver complètement le paysage, ce que je ne peux pas faire: nos contrôleurs de vue modale du navigateur Web ont besoin du paysage.

J'ai même essayé de sous-classer UITabBarController et de remplacer supportInterfaceOrientations pour renvoyer le masque en mode portrait uniquement, mais cela (même avec toutes les autres étapes ci-dessus) n'a pas résolu le problème.


Voici un lien vers un exemple de projet montrant le bogue.


59
jaredsinclair

Cela semble être un bogue dans iOS 8 lors de l'utilisation d'un UITabBarController comme contrôleur de vue racine. Une solution de contournement consiste à utiliser un UIViewController principalement Vanilla comme contrôleur de vue racine. Ce contrôleur de vue Vanilla servira de contrôleur de vue parent de votre contrôleur de barre d'onglets:

///------------------------
/// Portrait-Only Container
///------------------------

@interface PortraitOnlyContainerViewController : UIViewController

@end

@implementation PortraitOnlyContainerViewController

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

@end

// Elsewhere, in app did finish launching ...

PortraitOnlyContainerViewController *container = nil;

container = [[PortraitOnlyContainerViewController alloc] 
              initWithNibName:nil 
              bundle:nil];

[container addChildViewController:self.tabBarController];
self.tabBarController.view.frame = container.view.bounds;
[container.view addSubview:self.tabBarController.view];
[self.tabBarController didMoveToParentViewController:container];

[self.window setRootViewController:container];
6
jaredsinclair

J'ai eu le même problème lors du lancement de notre application en mode paysage sur un iPhone 6 Plus.

Notre correctif consistait à supprimer les orientations d'interface prises en charge en mode paysage du plist via les paramètres du projet:

Removed landscape orientation

et implémenter l'application: supportedInterfaceOrientationsForWindow: dans le délégué d'application:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
    return UIInterfaceOrientationMaskAllButUpsideDown;
}

Apparemment, les informations de votre plist sont de spécifier les orientations vers lesquelles votre application est autorisée à se lancer.

78
Stefan Church

La définition du statusBarOrientation du UIApplication semble fonctionner pour moi. Je l'ai placé dans le application:didFinishLaunchingWithOptions: méthode dans le délégué d'application.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    application.statusBarOrientation = UIInterfaceOrientationPortrait;

    // the rest of the method
}
38
neilvillareal

J'ai eu un problème très similaire. Je voulais forcer le mode portrait partout sauf pour lire des vidéos.

Ce que j'ai fait, c'est:

1) pour forcer l'orientation de l'application à être en mode portrait dans AppDelegate:

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    if ([window.rootViewController.presentedViewController isKindOfClass:[MPMoviePlayerViewController class]])
    {
        return UIInterfaceOrientationMaskAll;
    }
    return UIInterfaceOrientationMaskPortrait;
}

2) le lancement d'un contrôleur de vue modale vide a résolu le problème dans mon cas. Je le lance dans le viewDidLoad du premier contrôleur de vue qui se trouve à la racine de mon NavigationViewController (le premier contrôleur de vue visible après le lancement de l'application):

- (void)showAndHideNamelessViewControllerToFixOrientation {
    UIViewController* viewController = [[UIViewController alloc] init];
    [self presentViewController:viewController animated:NO completion:nil];
    [viewController dismissViewControllerAnimated:NO completion:nil];
}
2
Eurico Doirado

Veuillez essayer le code suivant. Ce problème est probablement dû à la taille de la fenêtre de clé lors du lancement en mode paysage.

// in application:didFinishLaunchingWithOptions: ...

self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
[self.window setFrame:[[UIScreen mainScreen] bounds]]; //<- ADD!!
1
fumiaki

Je souhaite uniquement que mon application s'ouvre en mode paysage (et ne présente pas le problème que vous décrivez ci-dessus sur l'iPhone 6 Plus), j'ai donc défini Landscape (left home button) et Landscape (right home button) comme les seules orientations autorisées dans le fichier PLIST de mon application. Cela résout le problème d'orientation à l'ouverture de mon application. Cependant, j'ai besoin que mon application prenne en charge le mode portrait pour une seule vue car j'affiche un UIImagePickerController dans mon application, qui Apple nécessite d'être affiché en mode portrait sur iPhone.

J'ai pu prendre en charge le portrait pour cette seule vue, tout en conservant l'ouverture de mon application en mode paysage, en incluant le code suivant dans AppDelegate:

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {

        return UIInterfaceOrientationMaskAllButUpsideDown;

    } else {

        return UIInterfaceOrientationMaskAll;

    }

}
1
abcd

Pas de chance pour moi la solution de contournement de Jared utilisant un contrôleur de vue de conteneur générique. J'ai déjà sous-classé le contrôleur de barre d'onglets avec lesInterfaceOrientations prises en charge sans chance également. Quelle que soit l'orientation du 6+ après le lancement, la fenêtre de la barre d'onglets signale frame = (0 0; 736 414)

Jusqu'à présent, la seule solution de contournement que j'ai trouvée est de forcer le cadre de la fenêtre après makeKeyAndVisible

[self.window makeKeyAndVisible]; self.window.frame = CGRectMake(0, 0, MIN(CGRectGetWidth(self.window.frame), CGRectGetHeight(self.window.frame)), MAX(CGRectGetWidth(self.window.frame), CGRectGetHeight(self.window.frame)));

1
Anthony

J'ai le même bug sur mon application, je l'ai compris avec ça solution

Tout d'abord, cela n'a pas fonctionné, mais après quelques Dig, je dois le faire sur le contrôleur initial après l'écran de démarrage.

La réponse est le langage OjbC permettez-moi de le mettre à jour vers Swift

override var shouldAutorotate: Bool {
    return true
}

override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return .portrait
}

N'oubliez pas que cela devrait sur le contrôleur de vue initial.

1
Gürhan KODALAK

Je suis dans la même situation et faire [self.window setFrame: ...] ne fonctionne pas pour moi.

Ajout de ce qui suit à la fin de l'application: didFinishLaunchingWithOptions est la seule chose que j'ai trouvée qui fonctionne. Il fait clignoter l'écran et n'est pas exactement propre et efficace.

J'ai ajouté ceci à la fin de l'application: didFinishLaunchingWithOptions:

UIViewController *portraitViewController = [[UIViewController alloc] init];
UINavigationController* nc = [[UINavigationController alloc] initWithRootViewController:portraitViewController];
[self.navController presentViewController:nc animated:NO completion:nil];
[self.navController dismissViewControllerAnimated:NO completion:nil];  
[UIViewController attemptRotationToDeviceOrientation];
0
James Grote

Pour ma part, j'avais le même problème que jaredsinclair, mais sous-classer un UIViewController avec la méthode supportedInterfaceOrientations ne résolvait pas le problème. Au lieu de cela, j'ai fait exactement ce qu'il a fait dans ma méthode appDidFinishLaunching de mon AppDelegate et j'ai ajouté mon UITabBarController enfant à un UIViewController normal plutôt qu'à sa sous-classe et ça a marché!

0
Will

Il suffit de supprimer tous les éléments dans l'orientation de l'interface prise en charge, sauf ce que vous voulez (je n'ai besoin que de Portrait) dans info.plist, cela fonctionnera pour moi enter image description here

0
abdul sathar

J'ai eu un problème similaire avec mon application s'exécute à la fois en mode paysage et portrait avec un UITabBarController comme contrôleur de vue racine.

Chaque fois que l'application était lancée en mode Paysage, la vue était incorrecte.

Tout ce que j'avais à faire: - supprimer l'affectation du contrôleur rootview dans le XIB. - Ajoutez-le manuellement une fois l'application lancée:


  • (void) applicationDidFinishLaunching: (UIApplication *) application {application.statusBarHidden = YES;

    [self.window setRootViewController: self.tabBarController];


Cela a résolu le problème.

0
de-bits