Chers développeurs, j'ai des problèmes avec AutoLayout dans Interface Builder (Xcode 5 / iOS 7). C'est très basique et important, donc je pense que tout le monde devrait savoir comment cela fonctionne correctement. S'il s'agit d'un bogue dans Xcode, il est critique!
Donc, chaque fois que j'ai une hiérarchie de vues comme celle-ci, je rencontre des problèmes:
>UIViewController
>> UIView
>>>UIScrollView
>>>>UILabel (or any other comparable UIKit Element)
Le UIScrollView a des contraintes solides, par exemple, 50 px de chaque côté (pas de problème). Ensuite, j'ajoute une contrainte Top Space à l'UILabel (pas de problème) (et je peux même épingler la hauteur / largeur de l'étiquette, ne change rien, mais ne devrait pas être nécessaire en raison de la taille intrinsèque de l'étiquette)
Le problème commence lorsque j'ajoute une contrainte de fin à l'UILabel:
Par exemple, Trailing Space to: Superview Equals: 25
Maintenant, deux avertissements se produisent - et je ne comprends pas pourquoi:
A) Ambiguïté de la taille du contenu défilable (la vue de défilement présente une hauteur / largeur de contenu défilant ambigu)
B) Vues mal placées (étiquette attendue: x = -67 réelle: x = 207
J'ai fait cet exemple minimal dans un nouveau projet que vous pouvez télécharger et j'ai joint une capture d'écran. Comme vous pouvez le voir, Interface Builder s'attend à ce que l'étiquette se trouve en dehors de la limite de UIScrollView (le rectangle en pointillés orange). La mise à jour du cadre du libellé avec l'outil Résoudre les problèmes le déplace là.
Remarque: si vous remplacez UIScrollView par UIView, le comportement est conforme aux attentes (le cadre de l'étiquette est correct et conforme à la contrainte). Il semble donc qu'il y ait un problème avec UIScrollView ou que je manque quelque chose d'important.
Lorsque j'exécute l'application sans mettre à jour le cadre du Label comme suggéré par IB, il est très bien positionné, exactement là où il est censé être et UIScrollView peut défiler. Si je mets à jour le cadre, l'étiquette est hors de vue et l'UIScrollView ne défile pas.
Aidez-moi Obi-Wan Kenobi! Pourquoi cette disposition ambiguë? Pourquoi cette vue déplacée?
Vous pouvez télécharger l'exemple de projet ici et essayer de comprendre ce qui se passe: https://github.com/Wirsing84/AutoLayoutProblem
UIScrollView
directement. Au lieu d'utiliserUICollectionView
ouUITableView
autant que possible, la plupart du temps, tout est possible avec ces éléments et cela donne également la simplicité, la lisibilité et la réutilisation !!!Réponses:
Je viens donc de trier de cette façon:
À l'intérieur de l'
UIScrollView
ajout d' unUIView
(on peut appeler celacontentView
);Dans ce cas
contentView
, définissez les marges supérieure, inférieure, gauche et droite à 0 (bien sûr à partir descrollView
laquelle est lasuperView
); Définissez également aligner le centre horizontalement et verticalement ;Terminé .
Maintenant, vous pouvez ajouter toutes vos vues en cela
contentView
, etcontentSize
lescrollView
sera automatiquement redimensionné en fonction ducontentView
.Mise à jour:
Certains cas particuliers sont couverts par cette vidéo publiée par @Sergio dans les commentaires ci-dessous.
la source
Cette erreur m'a pris un certain temps à rechercher, au début, j'ai essayé d'épingler la taille du ScrollView mais le message d'erreur indique clairement "taille du contenu". Je me suis assuré que tout ce que j'avais épinglé en haut du ScrollView était également épinglé en bas. De cette façon, ScrollView peut calculer la hauteur de son contenu en trouvant la hauteur de tous les objets et contraintes. Cela a résolu la hauteur du contenu ambigu, la largeur est assez similaire ... Au départ, la plupart des choses étaient centrées sur X dans le ScrollView, mais je devais également épingler les objets sur le côté du ScrollView. Je n'aime pas cela parce que l'iPhone6 pourrait avoir un écran plus large, mais cela supprimera l'erreur «largeur de contenu ambiguë».
la source
Xcode 11+
La manière la plus simple d'utiliser
autolayout
:UIScrollView
et épinglez-le0,0,0,0
à la vue d'ensemble (ou à la taille souhaitée)UIView
ScrollView, épinglez-le0,0,0,0
sur les 4 côtés et centrez-lehorizontally
etvertically
.bottom
etalign center Y
donnez la priorité à 250. (pour le changement de défilement horizontaltrailing
etalign center X
)UIScrollView
, sélectionnez l'inspecteur de taille et désélectionnezContent Layout Guides
.la source
C'est la réponse à ma question auto-répondue UIScrollView + Vue Centrée + Taille de Contenu Défilable Ambigous + plusieurs tailles d'iPhone .
Mais cela couvre également votre cas!
Voici donc l'état initial du cas le plus simple:
Has ambiguous scrollable content width
etHas ambiguous scrollable content height
.Tout ce que nous devons faire, c'est:
Important: vous devez ajouter des contraintes de fin et / ou de fond . Pas "leader et top" - ça ne marche pas!
Vous pouvez le vérifier dans mon exemple de projet , qui montre comment résoudre ce problème.
PS
Selon la logique - cette action devrait provoquer des "contraintes conflictuelles". Mais non!
Je ne sais pas pourquoi cela fonctionne et comment Xcode détecte quelle contrainte est la plus prioritaire (parce que je ne suis pas défini comme prioritaire pour ces contraintes explicitement). Je serai reconnaissant si quelqu'un explique pourquoi cela fonctionne dans les commentaires ci-dessous.
la source
Xcode 11+, Swift 5
Si vous vous demandez pourquoi toutes les réponses ne fonctionnent plus, assurez-vous que vous avez épinglé la vue de contenu (celle que vous avez placée dans la vue de défilement) au Guide de disposition du contenu de la vue de défilement et NON au Guide de disposition des cadres.
Les bords de la vue du contenu (début, fin, haut, bas) ne doivent pas être épinglés comme les premiers sur l'image - vers le guide de disposition du cadre
mais comme ça - au Content Layout Guide.
Et puis la plupart des réponses fonctionneront pour vous.
L'approche la plus simple se déroule maintenant comme ceci:
Dans l'ensemble, votre structure dans la mise en œuvre la plus simple ressemblera à ceci
la source
Vous devez créer un
UIView
sous-vue duUIScrollView
comme décrit ci-dessous:UIViewController
UIView
'Vue principale'UIScrollView
UIView
«Vue conteneur»La deuxième étape consiste à faire les
UIScrollView
contraintes. Je l'ai fait avec les contraintes supérieure, inférieure, avant et arrière de sa superView.Ensuite, j'ai ajouté les contraintes pour le conteneur de
UIScrollView
et c'est ici que le problème commence. Lorsque vous mettez les mêmes contraintes (haut, bas, début et fin), le Storyboard donne un message d'avertissement:"A une largeur de contenu défilant ambigu" et "A une hauteur de contenu défilant ambigu"
Continuez avec les mêmes contraintes ci-dessus, et ajoutez simplement les contraintes
Equal Height
etEqual Width
à votre vue de conteneur par rapport à la vue principale et non à votreUIScrollView
. En d'autres termes, les contraintes de la vue conteneur sont liées à la vue d'ensemble duUIScrollView
.Après cela, vous n'aurez plus d'avertissement dans votre Storyboard et vous pourrez continuer à ajouter les contraintes pour vos sous-vues.
la source
J'ai eu le même problème. Décochez cette case. Puisque vous définissez la taille du contenu dans le code.
la source
J'ai finalement compris cela, j'espère que c'est plus facile à comprendre.
Vous pouvez souvent contourner cet avertissement en ajoutant une UIView de base à la vue de défilement en tant que "vue de contenu", comme ils l'ont mentionné et en lui donnant la même taille que votre vue de défilement et, sur cette vue de contenu, définissez ces 6 paramètres.
Comme vous pouvez le voir, vous avez besoin de 6 paramètres au total! Ce qui .. dans des circonstances normales, vous dupliquez 2 contraintes mais c'est le moyen d'éviter cette erreur de storyboard.
la source
Je sais que je suis peut-être en retard, mais la prochaine solution résout ce genre de problèmes sans code supplémentaire , en utilisant simplement des storyboards:
Pour votre affichage de contenu, vous devez définir des contraintes pour les espaces de début / de fin / haut / bas pour faire défiler la vue et cela ne changera pas le cadre d'affichage de contenu , comme ceci:
Bien sûr, vous devez créer des contraintes supplémentaires pour la vue du contenu afin que la vue de défilement puisse connaître la taille du contenu. Par exemple, définissez une hauteur et un centre fixes x.
J'espère que cela t'aides.
la source
Pour moi, l'ajout d'un
contentView
n'a pas vraiment fonctionné comme suggéré. De plus, cela crée un surcoût en raison de la vue ajoutée (bien que je ne considère pas cela comme un gros problème). Ce qui a fonctionné le mieux pour moi, c'était juste de désactiver la vérification d' ambiguïté pour moiscrollView
. Tout se passe bien, donc je pense que ça va dans des cas simples comme le mien. Mais gardez à l'esprit que si d'autres contraintes pour votrescrollView
pause, l'Interface-Builder ne vous en avertira plus.la source
Découvrez ce tutoriel très rapide et pertinent sur la façon de faire fonctionner la vue de défilement et de la faire défiler entièrement avec la mise en page automatique. Maintenant, la seule chose qui me laisse encore perplexe est la raison pour laquelle la taille du contenu de la vue de défilement est toujours plus grande que nécessaire.
http://samwize.com/2014/03/14/how-to-use-uiscrollview-with-autolayout/
la source
Voir ci-dessous: affichage du contenu en scrollview vertical et horizontal centralisé. vous avez une erreur d'ambiguïté, assurez-vous toujours que deux éléments ajoutés dans la vue de défilement de votre vue de contenu sont 1) .bouton d'espace vers le conteneur.2) espace de fin à la contrainte qui est mis en évidence dans la capture d'écran,
ces contraintes signifient que dans le défilement, vous pouvez défiler après la hauteur ou la largeur de votre vue de contenu.
cela peut vous aider.
la source
J'ai résolu ce type de problème pour ma vue en utilisant "Résoudre les problèmes de disposition automatique"> "Ajouter des contraintes manquantes" pour la vue sélectionnée
Les deux contraintes suivantes résolvent mon problème:
dans lequel: en bas, en bas sont les derniers, en bas de UIScrollView
la source
L' utilisation contentView (
UView
) comme à l' intérieur du conteneurUIScrollView
, bâton aux bords (top
,bottom
,trailing
,leading
) de superview (UIScrollView
) etcontentView
devrait avoirequalwidth
etequalheight
à superview. Ce sont des contraintes. Et appel de méthode:Problèmes résolus pour moi.
la source
Approche Swift 4+:
1) Définissez les marges supérieure, inférieure, gauche et droite d'UIScrollView sur 0
2) À l'intérieur de UIScrollView, ajoutez une UIView et définissez les marges supérieure, inférieure, avant et arrière à 0 (égale aux marges UIScrollView).
3) La partie la plus importante est de définir la largeur et la hauteur, où la contrainte de hauteur doit avoir une faible priorité .
la source
La réponse de @Matteo Gobbi est parfaite, mais dans mon cas, la vue de défilement ne peut pas défiler, je supprime " aligner le centre Y " et ajoute " hauteur> = 1 ", la vue de défilement deviendra défilante
la source
Les personnes qui ont du mal avec uiscrollview qui ne font pas défiler définissent simplement la contrainte inférieure de votre vue de contenu avec la disposition inférieure de votre dernière vue (qui se trouve à l'intérieur de votre vue de contenu). N'oubliez pas de supprimer la contrainte Y centrale.
Reste que toutes les contraintes sont les mêmes que celles définies ci-dessus. Scrollview ne se préoccupe que d'obtenir la hauteur maximale de sa vue de contenu, et nous la définissons comme contrainte inférieure de la dernière vue, ce qui signifie que scrollview changera automatiquement son décalage de contenu.
Dans mon cas, la dernière vue était UILable sans aucune propriété de lignes = 0 (qui ajuste automatiquement sa hauteur en fonction de son contenu), ce qui augmente dynamiquement la hauteur de uilable et, finalement, notre zone de défilement augmente en raison de la disposition du bas de uilable est alignée avec le bas de notre vue de contenu, ce qui oblige scrollview à augmenter son décalage de contenu.
la source
J'ai fait une vidéo sur
youTube Scroll StackViews en utilisant uniquement le Storyboard dans Xcode
Je pense que 2 types de scénarios peuvent apparaître ici.
La vue à l'intérieur du scrollView -
UIView
)UIStackView
)Pour une vue défilante verticalement dans les deux cas, vous devez ajouter ces contraintes:
4 contraintes de haut, gauche, bas et droite.
Largeur égale à scrollview (pour arrêter le défilement horizontal)
Vous n'avez pas besoin d'autres contraintes pour les vues qui ont leur propre hauteur de contenu intrinsèque.
Pour les vues qui n'ont pas de hauteur de contenu intrinsèque, vous devez ajouter une contrainte de hauteur. La vue défilera uniquement si la contrainte de hauteur est supérieure à la hauteur de scrollView.
la source
Production:
la source
Dans mon cas, j'ai reçu le problème de la taille du contenu et de l'ambiguïté de la taille du contenu sur l'iPad, mais je travaillais dans le cas de l'iPhone. J'ai effectué les modifications suivantes dans le storyboard pour résoudre le problème.
la source
Défilement vertical
la source
Ce que j'ai fait, c'est créer une vue de contenu séparée, comme indiqué ici.
La vue de contenu est de forme libre et peut contenir toutes les sous-vues avec leurs propres contraintes par rapport à la contentView.
UIScrollView est ajouté au contrôleur de vue principal.
J'ajoute par programme le contentView qui est lié via IBOutlet à la classe et définit le contentView de UIScrollView.
la source
J'obtenais la même erreur .. j'ai fait suivant
Ajoutez maintenant le début / fin / haut / bas pour scrollView (2) puis UIView (3).
Sélectionnez Affichage (1) et Affichage (3) définissez également la taille et le poids .. son résolu mon problème.
J'ai fait la vidéo qui vous aidera:
https://www.youtube.com/watch?v=s-CPN3xZS1A
la source
[testé dans XCode 7.2 et pour iOS 9.2]
Ce qui a supprimé les erreurs et les avertissements du Storyboard pour moi était de définir la taille intrinsèque de la vue de défilement et de la vue de contenu (dans mon cas, une vue de pile) sur Placeholder . Ce paramètre se trouve dans l'inspecteur de taille dans Storyboard. Et cela dit - La définition d'une taille de contenu intrinsèque au moment de la conception affecte uniquement une vue lors de la modification dans Interface Builder. La vue n'aura pas cette taille de contenu intrinsèque lors de l'exécution.
Donc, je suppose que nous ne nous trompons pas en réglant cela.
Remarque: Dans le storyboard, j'ai épinglé tous les bords de scrollview à la vue d'ensemble et tous les bords de stackview à la scrollview. Dans mon code, j'ai défini les translatesAutoresizingMaskIntoConstraints comme faux pour la vue de défilement et la vue de pile. Et je n'ai pas mentionné de taille de contenu. Lorsque la vue de la pile se développe dynamiquement, les contraintes définies dans le storyboard garantissent que la pile peut défiler.
L'avertissement du storyboard me rendait fou et je ne voulais pas centrer les choses horizontalement ou verticalement juste pour supprimer l'avertissement.
la source
Si quelqu'un obtient un comportement où vous remarquez la barre de défilement sur les rouleaux de droite mais le contenu ne bouge pas, ce fait mérite probablement d'être pris en considération:
Cela vient de la documentation d'Apple . Par exemple, si vous épingliez accidentellement votre étiquette / bouton / img / vue supérieur à la vue en dehors de la zone de défilement (peut-être un en-tête ou quelque chose juste au-dessus de scrollView?) Au lieu de contentView, vous feriez tout votre contentView en place.
la source
Comme mentionné dans les réponses précédentes, vous devez ajouter une vue personnalisée dans la vue de défilement:
Ajoutez toutes vos sous-vues à la vue du contenu. À un moment donné, vous verrez une vue de contenu de défilement avec un avertissement de taille de contenu ambigu, vous devez sélectionner la vue de contenu et cliquer sur le bouton "Résoudre les problèmes de mise en page automatique" (dans le coin inférieur droit de la mise en page IB), puis sélectionner "Ajouter manquant contraintes ".
À partir de maintenant, lorsque vous exécutez le projet, la vue de défilement mettra automatiquement à jour sa taille de contenu, aucun code supplémentaire n'est nécessaire.
la source
Dans mon cas - une vue de défilement horizontal - j'ai également dû ajouter des contraintes de largeur et de hauteur pour chaque enfant de la vue de défilement, bien que la note technique d'Apple ne vous le dise pas.
la source
Définissez la taille de ViewController (celle contenant UIScrollView) sur Freeform dans l'inspecteur de taille dans Interface Builder et tout devrait fonctionner.
Paramètre de forme libre dans l'inspecteur de taille dans Interface Builder pour l'UIViewcontroller contenant
la source
Si vous avez encore des problèmes avec UIScrollView, juste désactiver le contenu mise en page Guides (Choisissez votre ScrollView dans Xcode Interface Builder -> choisissez Inspecteur Taille dans le panneau droit -> deselect 'Contenu Guides de mise en page) ou essayez ces étapes: Xcode 11 défilement des mises en page de vue - il peut être utile pour un nouveau style de mise en page. Fonctionne bien sous macOS 10.15.2, Xcode 11.3.1, pour 05.02.2020
voir capture d'écran
la source
Utilisation de la mise en page automatique
Ajoutez votre vue de défilement dans une vue bien définie, puis ajoutez la vue de pile dans la vue de défilement
Ajoutez des contraintes en haut, à gauche, à droite, en bas, au centre X et au centre Y de la vue de défilement et de la vue de pile à leurs super vues pertinentes
Assurez-vous que les contraintes sont liées de la vue de la pile à la vue d'ensemble légitime (scrollview) car le paramètre par défaut actuel consiste à ajouter une contrainte Aligner en haut et non pas une espace en haut.
la source