web-dev-qa-db-fra.com

Problèmes de mise en page automatique du guide de mise en page iOS 8

L'un des écrans de mon application s'est complètement cassé lors de la mise à jour vers le SDK iOS 8. Le problème semble être que le guide de mise en page supérieur se déplace vers le haut au lieu d'être une "ancre" pour le reste des vues.

Voici à quoi ressemblait la vue sur iOS 7:

iOS 7 Screen

Voici à quoi cela ressemble dans iOS 8 (capturé à partir du débogueur Xcode 6 View Hierarchy):

iOS 7 Screen

Comme vous pouvez le voir, la vue apparaît bien au-dessus de la barre de navigation. Il y a deux contraintes sur le guide de mise en page supérieur, une pour la vue supérieure de l'image et une pour la vue blanche en dessous. Il n'y a aucune contrainte sur le guide de mise en page inférieur, seulement des contraintes de hauteur sur les vues.

Pour une raison quelconque, iOS 8 décide de pousser le guide de mise en page supérieur vers {0 -255; 0 0} après [self.view layoutIfNeeded] est appelé pour la première fois. De plus, les limites de la vue semblent parfois trop grandes pour l'appareil (c'est-à-dire qu'elles apparaissent exactement comme dans le storyboard unifié (600x600), au lieu de 320x480/320x568.

Qu'est-ce qui a changé dans iOS 8 qui pourrait bousiller la mise en page?

[EDIT] Voici une liste complète des contraintes sur la vue:

(lldb) po self.view.constraints
<__NSArrayM 0x786ac520>(
    <NSLayoutConstraint:0x7c377bd0 V:[_UILayoutGuide:0x7c372f60]-(0)-[UIView:0x7c373120]>,
    <NSLayoutConstraint:0x7c377c00 UIView:0x7c373120.width == UIView:0x7c3730b0.width>,
    <NSLayoutConstraint:0x7c377c30 UIView:0x7c3730b0.centerX == UIView:0x7c373120.centerX>,
    <NSLayoutConstraint:0x7c377c60 H:|-(0)-[UIView:0x7c3716f0]   (Names: '|':UIView:0x7c3730b0 )>,
    <NSLayoutConstraint:0x7c377c90 UIView:0x7c3716f0.width == UIView:0x7c3730b0.width>,
    <NSLayoutConstraint:0x7c372f30 V:[_UILayoutGuide:0x7c372f60]-(129)-[UIView:0x7c3716f0]>
)
23
David Ganster

Extend Edges > Under Top Bars est vérifié par défaut dans la section Étendre les bords de l'inspecteur d'attributs.

Essayez de décocher Under Top Bars.

Cela m'a aidé à plusieurs reprises lorsque j'ai eu un comportement étrange comme celui-ci.

Veuillez noter qu'il s'agit d'une propriété UIViewController, vous pouvez donc la définir dans le code si vous le souhaitez.

Under Top Bars option in Interface Builder

43
Blacky

J'utilise Xcode 6.3.1 et il semble que le bogue soit de retour dans cette version (il aurait été corrigé en 5.1). Je n'ai pas pu trouver de solution de contournement sur SO donc j'ai dû chercher un peu plus sur Google et la voici:

au lieu de faire le Ctrl + glisser habituel dans IB, sélectionnez simplement la vue pour laquelle vous voulez le faire et allez dans Editeur -> Pin -> Top Space to Superview.

Voici la source: LIEN Cela m'a aidé dans mon cas.

5
JakeP

Vous pouvez utiliser UIBarPositionTopAttached ou vous pouvez utiliser des limites et des cadres d'affichage, je peux également vous suggérer et vous lier à documentation d'Apple qui vous mettrait un certain temps à résoudre le problème.

La façon la meilleure et la plus simple de résoudre ce problème consiste à simplement intégrer votre contrôleur de vue dans un contrôleur de navigation et c'est tout. Vous pouvez le faire en sélectionnant simplement le contrôleur de vue et en allant dans Éditeur> Intégrer dans> Contrôleur de navigation. (S'il y a du contenu sur votre ancienne barre de navigation, vous pouvez d'abord le faire glisser vers le bas, incorporer le contrôleur de vue dans le contrôleur de navigation, puis déplacez les boutons de la barre sur la nouvelle barre de navigation, puis supprimez l'ancienne barre de navigation)

[~ # ~] ou [~ # ~]

Définissez la propriété translucent de la barre de navigation sur NO:

self.navigationController.navigationBar.translucent = NO;

Cela empêchera la vue d'être encadrée sous la barre de navigation et la barre d'état.

Si vous devez afficher et masquer la barre de navigation, utilisez

 if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
    self.edgesForExtendedLayout = UIRectEdgeNone;   // iOS 7 specific

dans votre méthode viewDidLoad.

J'espère que l'un d'eux résoudra votre problème.

5
Mrunal

J'ai aussi un problème comme ça. Si vous exécutez uniquement sur iOS8, vous pouvez modifier les contraintes de "topLayoutGuide.bottom-myView.top" en "topLayoutGuide.top-myView.top". Mais cela rompra l'interface utilisateur pour iOS7. Il est possible d'écrire une solution de contournement comme celle-ci dans le code pour prendre en charge les deux versions, mais il n'y a aucune chance que l'interface utilisateur fonctionne correctement pour les deux versions lors de la création de l'interface utilisateur dans les storyboards.

2