Disons que j'ai ajouté plus de vues dans UIStackView qui peuvent être affichées, comment puis-je faire le UIStackView
défilement?
ios
uiscrollview
uistackview
itsaboutcode
la source
la source
Réponses:
Dans le cas où quelqu'un cherche une solution sans code , j'ai créé un exemple pour le faire complètement dans le storyboard, en utilisant la mise en page automatique.
Vous pouvez l'obtenir auprès de github .
Fondamentalement, pour recréer l'exemple (pour le défilement vertical):
UIScrollView
et définissez ses contraintes.UIStackView
auUIScrollView
Leading
,Trailing
,Top
etBottom
devrait être égal à ceux deUIScrollView
Width
contrainte égale entre leUIStackView
etUIScrollView
.UIStackView
UIViews
laUIStackView
Échange
Width
de l'Height
étape 4, et ensembleAxis
=Horizontal
dans l' étape 5, pour obtenir un UIStackView horizontal.la source
Le guide de mise en page automatique d'Apple comprend une section entière sur l'utilisation des vues de défilement . Quelques extraits pertinents:
En outre:
Pour résumer, la vue de contenu de la vue de défilement (dans ce cas, une vue de pile) doit être épinglée sur ses bords et avoir sa largeur et / ou sa hauteur autrement limitée. Cela signifie que le contenu de la vue de pile doit être contraint (directement ou indirectement) dans la ou les directions dans lesquelles le défilement est souhaité, ce qui pourrait signifier ajouter une contrainte de hauteur à chaque vue à l'intérieur d'une vue de pile à défilement vertical, par exemple. Voici un exemple de comment autoriser le défilement vertical d'une vue de défilement contenant une vue de pile:
la source
Need constraints for: Y position or height.
cette erreur disparaît uniquement si vous définissez à la fois une contrainte de largeur et de hauteur pour la vue de la pile, ce qui désactive le défilement vertical. Ce code fonctionne-t-il toujours pour vous?Les contraintes dans la réponse la plus votée ici ont fonctionné pour moi, et j'ai collé une image des contraintes ci-dessous, telle que créée dans mon storyboard.
J'ai cependant rencontré deux problèmes dont d'autres devraient être conscients:
Après avoir ajouté des contraintes similaires à celles de la réponse acceptée, j'obtiendrais l'erreur de mise en page automatique rouge
Need constraints for: X position or width
. Cela a été résolu en ajoutant un UILabel comme sous-vue de la vue de la pile.J'ajoute les sous-vues par programme, donc à l'origine je n'avais pas de sous-vues sur le storyboard. Pour supprimer les erreurs de mise en page automatique, ajoutez une sous-vue au storyboard, puis supprimez-la lors du chargement avant d'ajouter vos vraies sous-vues et contraintes.
J'ai essayé à l'origine d'ajouter
UIButtons
à UIStackView. Les boutons et les vues se chargeraient, mais la vue de défilement ne défilerait pas . Cela a été résolu en ajoutantUILabels
à la vue de la pile au lieu de boutons. En utilisant les mêmes contraintes, cette hiérarchie de vues avec les UILabels défile mais pas les UIButtons.Je suis confus par ce problème, car les UIButtons ne semblent avoir un IntrinsicContentSize (utilisé par la vue Stack). Si quelqu'un sait pourquoi les boutons ne fonctionnent pas, j'aimerais savoir pourquoi.
Voici ma hiérarchie de vue et les contraintes, pour référence:
la source
Comme le dit Eik,
UIStackView
etUIScrollView
jouez bien ensemble, voyez ici .La clé est que le
UIStackView
gère la hauteur / largeur variable pour différents contenus et le faitUIScrollView
alors bien son travail de défilement / rebondir ce contenu:la source
Je cherchais à faire la même chose et suis tombé sur cet excellent post. Si vous souhaitez le faire par programme à l'aide de l'API d'ancrage, c'est la voie à suivre.
Pour résumer, intégrez votre
UIStackView
dans votreUIScrollView
et définissez les contraintes d'ancrage duUIStackView
pour correspondre à celles duUIScrollView
:la source
À jour pour 2020.
100% storyboard OU 100% code.
Voici l'explication la plus simple possible:
Avoir une scène vierge en plein écran
Ajoutez une vue de défilement. Faites glisser la souris de la vue de défilement à la vue de base , ajoutez gauche-droite-haut-bas, tout à zéro.
Ajoutez une vue de pile dans la vue de défilement. Faites glisser la vue de la pile vers la vue de défilement tout en maintenant la touche Ctrl enfoncée , ajoutez gauche-droite-haut-bas, tout à zéro.
Mettez deux ou trois étiquettes dans la vue de la pile.
Pour plus de clarté, rendez la couleur d'arrière-plan de l'étiquette rouge. Réglez la hauteur de l'étiquette sur 100.
Réglez maintenant le Définissez largeur de chaque UILabel:
Étonnamment, faites glisser
UILabel
la souris de la vue vers la vue de défilement, pas vers la vue de la pile, et sélectionnez des largeurs égales .Répéter:
Ne contrôlez pas le glissement de l'UILabel vers le parent de l'UILabel - allez chez le grand-parent. (En d'autres termes, allez jusqu'au mode défilement, ne passez pas au mode pile.)
C'est si simple. Voilà le secret.
Vous avez terminé.
Conseil: vous devez ajouter une hauteur à chaque nouvel élément . Chaque élément d'une vue de pile de défilement doit avoir une taille intrinsèque (telle qu'une étiquette) ou ajouter une contrainte de hauteur explicite.
L'approche alternative:
Dans ce qui précède: de manière surprenante, définissez les largeurs des étiquettes UIL sur la largeur de la vue de défilement (pas la vue de la pile).
Alternativement...
Faites glisser de la vue de la pile vers la vue de défilement et ajoutez une contrainte "largeur égale". Cela semble étrange parce que vous avez déjà épinglé de gauche à droite , mais c'est comme ça que vous le faites . Peu importe à quel point il semble étrange que ce soit le secret.
Vous avez donc deux options:
ou
Pour être clair, faites UNE de ces méthodes, ne faites PAS les deux.
la source
Défilement horizontal (UIStackView dans UIScrollView)
Pour le défilement horizontal. Créez d'abord un
UIStackView
et unUIScrollView
et ajoutez-les à votre vue de la manière suivante:Se souvenant de mettre la
translatesAutoresizingMaskIntoConstraints
àfalse
leUIStackView
etUIScrollView
:Pour que tout fonctionne, les ancres arrière, avant, supérieure et inférieure
UIStackView
doivent être égales auxUIScrollView
ancres:Mais la largeur de l'ancre
UIStackView
doit être égale ou supérieure à la largeur de l'UIScrollView
ancre:Maintenant, ancrez votre
UIScrollView
, par exemple:Ensuite, je suggère d'essayer les paramètres suivants pour l'
UIStackView
alignement et la distribution:Enfin, vous devrez utiliser la
addArrangedSubview:
méthode pour ajouter des sous-vues à votre UIStackView.Encarts de texte
Une fonctionnalité supplémentaire que vous pourriez trouver utile est que, parce que le contenu se
UIStackView
trouve dans un,UIScrollView
vous avez maintenant accès à des encarts de texte pour rendre les choses un peu plus jolies.la source
Ajoutez simplement ceci à
viewdidload
:source: https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/LayoutUsingStackViews.html
la source
Vous pouvez essayer ScrollableStackView : https://github.com/gurhub/ScrollableStackView
C'est une bibliothèque compatible avec Objective-C et Swift. Il est disponible via CocoaPods .
Exemple de code (Swift)
Exemple de code (Objective-C)
la source
Si vous avez une contrainte pour centrer la vue de pile verticalement à l'intérieur de la vue de défilement, supprimez-la simplement.
la source
Exemple pour une vue de pile / défilement verticale (en utilisant la mise
EasyPeasy
en page automatique):Assurez-vous simplement que la hauteur de chaque sous-vue est définie!
la source
Avant tout, concevez votre vue, de préférence dans quelque chose comme Sketch ou faites-vous une idée de ce que vous voulez en tant que contenu déroulant.
Ensuite, rendez le contrôleur de vue libre (choisissez parmi l'inspecteur d'attributs) et définissez la hauteur et la largeur en fonction de la taille du contenu intrinsèque de votre vue (à choisir dans l'inspecteur de taille).
Après cela, dans le contrôleur de vue, mettez une vue de défilement et c'est une logique, que j'ai trouvé fonctionner presque tout le temps dans iOS (cela peut nécessiter de parcourir la documentation de cette classe de vue que l'on peut obtenir via la commande + cliquez sur cette classe ou via googler)
Si vous travaillez avec deux ou plusieurs vues, commencez d'abord par une vue qui a été introduite plus tôt ou qui est plus primitive, puis passez à la vue qui a été introduite plus tard ou qui est plus moderne. Donc, ici, puisque la vue de défilement a été introduite en premier, commencez par la vue de défilement puis passez à la vue de la pile. Ici, mettez les contraintes de défilement à zéro dans toutes les directions par rapport à sa super vue. Placez toutes vos vues dans cette vue de défilement, puis placez-les en vue de pile.
Tout en travaillant avec la vue pile
Commencez d'abord par les motifs vers le haut (approche ascendante), c'est-à-dire si vous avez des étiquettes, des champs de texte et des images dans votre vue, puis disposez ces vues en premier (à l'intérieur de la vue de défilement) et ensuite mettez-les dans la vue de la pile.
Après cela, ajustez la propriété de la vue de la pile. Si la vue souhaitée n'est toujours pas obtenue, utilisez une autre vue de pile.
Après avoir créé votre vue, placez une contrainte entre la vue de la pile mère et la vue de défilement, tandis que les enfants de contrainte empilent la vue avec la vue de la pile mère. J'espère qu'à ce moment cela devrait fonctionner correctement ou vous pouvez recevoir un avertissement de Xcode donnant des suggestions, lisez ce qu'il dit et mettez-les en œuvre. Si tout va bien maintenant vous devriez avoir une vue fonctionnante selon vos espérances :).
la source
Pour les vues imbriquées ou simples, la vue de défilement doit avoir une largeur fixe avec la vue racine. La vue de la pile principale qui se trouve à l'intérieur de la vue de défilement doit définir la même largeur. [Ma vue de défilement est inférieure à une vue, ignorez-la]
la source
Si quelqu'un cherche un défilement horizontal
la source
Placez une vue de défilement sur votre scène et redimensionnez-la afin qu'elle remplisse la scène. Ensuite, placez une vue de pile dans la vue de défilement et placez le bouton Ajouter un élément dans la vue de pile. Dès que tout est en place, définissez les contraintes suivantes:
code:
Stack View.Width = Scroll View.Width
est la clé.la source
Ajout d'une nouvelle perspective pour macOS Catalyst. Étant donné que les applications macOS prennent en charge le redimensionnement de la fenêtre, il est possible que vous
UIStackView
passiez d'un état non défilant à un état défilant, ou vice versa. Il y a deux choses subtiles ici:UIStackView
est conçu pour s'adapter à tous les domaines qu'il peut.UIScrollView
tentera de redimensionner ses limites pour tenir compte de la zone nouvellement gagnée / perdue sous votre barre de navigation (ou barre d'outils dans le cas des applications macOS).Cela créera malheureusement une boucle infinie. Je ne suis pas très familier avec
UIScrollView
et sonadjustedContentInset
, mais à partir de mon journal dans salayoutSubviews
méthode, je vois le comportement suivant:UIScrollView
tente de réduire ses limites (car pas besoin de la zone sous la barre d'outils).UIStackView
suit.UIScrollView
n'est pas satisfait et décide de revenir aux limites plus larges. Cela me semble très étrange, car ce que je vois dans le journal, c'est queUIScrollView.bounds.height == UIStackView.bounds.height
.UIStackView
suit.Il me semble que deux étapes régleraient le problème:
UIStackView.top
surUIScrollView.topMargin
.contentInsetAdjustmentBehavior
sur.never
.Ici, je suis concerné par une vue défilante verticalement avec une croissance verticale
UIStackView
. Pour une paire horizontale, modifiez le code en conséquence.J'espère que cela aidera n'importe qui à l'avenir. Je n'ai trouvé personne qui en parle sur Internet et il m'a fallu beaucoup de temps pour comprendre ce qui s'est passé.
la source