2014-09-03 8 views
0

J'ai un problème plutôt ennuyeux avec les contraintes de mise en page automatique mis sur un UIScrollView et ses sous-vues. Lorsque l'orientation de l'appareil change, il se casse une contrainte avec l'avertissement suivant:Contraintes de mise en page automatique UIScrolView briser sur la rotation de l'appareil

Unable to simultaneously satisfy constraints. 
Probably at least one of the constraints in the following list is one you don't want. 
Try this: (1) look at each constraint and try to figure out which you don't expect; 
(2) find the code that added the unwanted constraint or constraints and fix it. 
(Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSLayoutConstraint:0x7a1b1830 V:[UIView:0x7a1b0520(768)]>", 
    "<NSLayoutConstraint:0x7a1c5990 V:[UIView:0x7a1bcf50(1024)]>", 
    "<NSLayoutConstraint:0x7a17aa70 V:|-(0)-[UIView:0x7a1b0520] (Names: '|':UIScrollView:0x7a176520)>", 
    "<NSLayoutConstraint:0x7a1c49c0 V:[UIView:0x7a1b0520]-(0)-| (Names: '|':UIScrollView:0x7a176520)>", 
    "<NSLayoutConstraint:0x7a172620 V:[UIView:0x7a1bcf50]-(0)-| (Names: '|':UIScrollView:0x7a176520)>", 
    "<NSLayoutConstraint:0x7a172650 V:|-(0)-[UIView:0x7a1bcf50] (Names: '|':UIScrollView:0x7a176520)>" 
) 

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7a1c5990 V:[UIView:0x7a1bcf50(1024)]> 

J'ai mis en place une vue de défilement dans mon story-board et il contient deux conteneurs vues sous. La vue de défilement elle-même est épinglée sur les quatre côtés de l'aperçu (Editeur/Épingle/En-tête, Traînant-, Haut-, En-dessous de l'espace). Les deux conteneurs ont leurs bords épinglés à la vue de défilement avec des contraintes de mise en page automatique mais la largeur des deux est définie comme fixe sur le storyboard, voir att. Image:

enter image description here

La largeur et la hauteur des deux réservoirs est mis à jour par l'intermédiaire d'un code, une fois initialement en viewDidLoad() et à chaque changement d'orientation des appareils, en didRotateFromInterfaceOrientation():

_primaryWidth.constant = view.bounds.size.width 
    _primaryHeight.constant = view.bounds.size.height 
    _secondaryWidth.constant = _primaryWidth.constant - 200 
    _secondaryHeight.constant = _primaryHeight.constant 

Ceci est lorsque le dessus l'avertissement apparaît et les contraintes se rompent et la mise en page passe à l'eau. Quelqu'un peut-il me dire pourquoi cela se passe et comment y remédier?

(Notez le moins 200. En effet, le récipient droit devrait avoir une largeur plus petite. Mais il ne touche pas la question. Les contraintes se brisent même sans cela.)

+0

Vous n'avez pas besoin de changer la hauteur et la largeur car l'autolayout le ferait pour vous. Aussi cet avertissement est quand vous appliquez l'autolayout excessif alors exigé alors mieux lu sur autolayout et essayez avec un échantillon simple pour le comprendre. – nikhil84

+0

Si je ne mets pas à jour la largeur/hauteur des deux conteneurs après la rotation du périphérique, ils ne mettront pas à jour leur taille à l'écran w/h ce qui entraînera leur défilement vertical et de mauvaises tailles. – BadmintonCat

+0

Donc autolayout est pour prendre le contrôle de l'ajustement de votre mise en page. Vous devriez opter pour autolayout par programme plutôt IB. – nikhil84

Répondre

2

Vous avez des contraintes qui épingle les bords de la vue déroulante jusqu'aux bords de l'écran qui fonctionne à la fois en mode portrait et paysage.Vous avez également une contrainte qui définit la hauteur de l'une de vos vues à 1024.

En portrait ça marche, mais le moment vous faites pivoter au paysage vous ne pouvez pas avoir quelque chose être 1024 hauteur épinglé sur le bord de l'écran sur le dessus d'un fond parce que l'écran est seulement 768 de hauteur. Il faut y aller et vous pouvez voir lequel obtient la hache.

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7a1c5990 V:[UIView:0x7a1bcf50(1024)]> 

Enlever les contraintes de hauteur et tout ira bien. Pourquoi auriez-vous besoin d'eux de toute façon? Vous voulez que les vues soient épinglées sur le bord de l'écran/aperçu quelle que soit la taille de votre donnée. Des valeurs non arbitraires vous permettront également de transporter le même code/la même mise en page vers d'autres appareils ou sous-vues sans modification de mise en page.

+0

Merci pour les indices @DBD, mais je n'ai pas de contrainte dans le storyboard qui est réglé sur 1024 height. Le seul endroit où la hauteur des contraintes de vue de conteneur est mise à jour est dans le didRotateFromInterfaceOrientation() comme dans le code ci-dessus.Et ce serait nécessaire car sinon la hauteur des vues du conteneur ne sont pas les mêmes que la hauteur de l'écran. – BadmintonCat

+0

Wow! À quel point la mise en page automatique peut-elle être déroutante ?! Je pensais presque compris. Ajout de contraintes de largeur des deux conteneurs dans la vue déroulante, puis application de «Ajouter des contraintes manquantes». Cela devient presque parfait, même en tournant sur Paysage. Mais revenir à Portrait et la largeur et la hauteur de la deuxième vue du conteneur ne sont pas mises à jour. Temps perdu sur cette question: 3.45h. – BadmintonCat

+0

Compris! Il y avait une largeur prise à partir d'une mauvaise vue dans une autre classe apparentée qui causait la taille à gâcher, étrangement. – BadmintonCat

Questions connexes