Est-il possible pour UIStackView de défiler?

210

Disons que j'ai ajouté plus de vues dans UIStackView qui peuvent être affichées, comment puis-je faire le UIStackViewdéfilement?

itsaboutcode
la source
Pourquoi n'utilisez-vous pas une vue de défilement avec une (ou plusieurs) vues de pile pour le contenu?
Wain
2
La solution en une phrase est que pour la largeur, vous faites glisser la commande vers la vue de défilement des grands-parents, PAS la vue de la pile parent. Expliqué dans ma réponse!
Fattie
Comment intégrer UIStackView dans UIScrollView dans iOS github.com/onmyway133/blog/issues/324
onmyway133
Concernant cette question critique dans iOS. En fait, il y a deux (et seulement deux) façons de le faire - ce sont les seules façons de le faire et vous devez suivre exactement l'une des deux procédures. Ma réponse ci-dessous est toujours mise à jour.
Fattie
OUI. Vous DEVEZ avoir une UIView intermédiaire comme vue de contenu de UIScrollView. Placez ensuite UIStackView comme vue enfant de la vue de contenu. raywenderlich.com/…
poGUIst

Réponses:

578

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):

  1. Créez un UIScrollViewet définissez ses contraintes.
  2. Ajoutez un UIStackViewauUIScrollView
  3. Définissez les contraintes: Leading, Trailing, Topet Bottomdevrait être égal à ceux deUIScrollView
  4. Configurez une Widthcontrainte égale entre le UIStackViewet UIScrollView.
  5. Définissez Axe = Vertical, Alignment = Fill, Distribution = Equal Spacing et Spacing = 0 sur le UIStackView
  6. Ajouter un certain nombre de UIViewslaUIStackView
  7. Courir

Échange Widthde l' Heightétape 4, et ensemble Axis= Horizontaldans l' étape 5, pour obtenir un UIStackView horizontal.

Arjan
la source
55
Merci! "4. Configurez une contrainte de largeur égale entre UIStackView et UIScrollView." était la clé;)
Blank
19
Le numéro 6. est également important. Je voulais ajouter toutes les vues dans le code, mais la disposition automatique affiche les contraintes manquantes dans IB.
avant le
11
Salut gaes, il semble que cette solution ne fonctionne pas pour le défilement horizontal. À l'étape 4, au lieu de définir une largeur égale, je suppose de définir une hauteur égale et Axis = Horizontal. J'ai essayé ça et ça ne marche pas.
Seto Elkahfi
5
L'ajout d'une contrainte afin que stackview et scrollview aient des largeurs égales supprimera les avertissements du générateur d'interface, mais le défilement sera désactivé. Le défilement ne se produit que lorsque la vue du contenu à l'intérieur de la vue de défilement est plus grande que la vue de défilement!
Jason Moore
6
Pour développer le point 6. Si la vue de la pile ne comportait aucun élément mais que toutes les contraintes sont en place, vous obtenez "Contraintes de la vue de défilement pour la position ou la hauteur Y". Le simple ajout d'une étiquette dans la vue de la pile fait disparaître cet avertissement!
Faisal Memon
45

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:

  1. Épinglez les bords supérieur, inférieur, avant et arrière de la vue de contenu aux bords correspondants de la vue de défilement. La vue de contenu définit maintenant la zone de contenu de la vue de défilement.
  2. (Facultatif) Pour désactiver le défilement horizontal, définissez la largeur de la vue de contenu égale à la largeur de la vue de défilement. La vue de contenu remplit maintenant la vue de défilement horizontalement.
  3. (Facultatif) Pour désactiver le défilement vertical, définissez la hauteur de la vue de contenu égale à la hauteur de la vue de défilement. La vue de contenu remplit maintenant la vue de défilement horizontalement.

En outre:

Votre mise en page doit définir entièrement la taille de la vue du contenu (sauf lorsque défini aux étapes 5 et 6). … Lorsque la vue du contenu est plus haute que la vue de défilement, la vue de défilement permet le défilement vertical. Lorsque la vue de contenu est plus large que la vue de défilement, la vue de défilement permet le défilement horizontal.

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:

// Pin the edges of the stack view to the edges of the scroll view that contains it
stackView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
stackView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
stackView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
stackView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true

// Set the width of the stack view to the width of the scroll view for vertical scrolling
stackView.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true
titaniumdecoy
la source
1
Merci, mais en omettant la contrainte de hauteur (pour permettre le défilement vertical), cette erreur se produit dans Storyboard: 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?
Crashalot
@Crashalot Pour éliminer cette erreur, vous devez ajouter une sous-vue à la vue de la pile; voir ma réponse ci-dessous.
pkamb
17

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:

  1. 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.

  2. 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 ajoutant UILabelsà 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:

contraintes pour la vue de pile dans la vue de défilement [1]

pkamb
la source
3
vous venez de me sauver un tas d'heures de tête se cogner contre le mur et la frustration, je suis exactement dans la même situation et je n'ai pas pu comprendre la raison de l'avertissement et pourquoi ne fonctionne pas avec des boutons. Pourquoi Apple pourquoi!?
PakitoV
15

Comme le dit Eik, UIStackViewet UIScrollViewjouez bien ensemble, voyez ici .

La clé est que le UIStackViewgère la hauteur / largeur variable pour différents contenus et le fait UIScrollViewalors bien son travail de défilement / rebondir ce contenu:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    scrollView.contentSize = CGSize(width: stackView.frame.width, height: stackView.frame.height)       
}
user1307434
la source
2
Il n'est pas nécessaire de combiner la mise en page manuelle et automatique pour permettre une vue de pile déroulante. Il vous suffit de restreindre la largeur et / ou la hauteur de la vue de pile. Voir ma réponse pour plus de détails et un lien vers les documents Apple pertinents.
titaniumdecoy
L'exemple github fonctionnait parfaitement et était très clair. Merci d'avoir partagé.
Behr
stackView.translatesAutoresizingMaskIntoConstraints = false, cela a fait l'affaire dans mon cas
Howl Jenkins
10

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 UIStackViewdans votre UIScrollViewet définissez les contraintes d'ancrage du UIStackViewpour correspondre à celles du UIScrollView:

stackView.leadingAnchor.constraintEqualToAnchor(scrollView.leadingAnchor).active = true
stackView.trailingAnchor.constraintEqualToAnchor(scrollView.trailingAnchor).active = true
stackView.bottomAnchor.constraintEqualToAnchor(scrollView.bottomAnchor).active = true
stackView.topAnchor.constraintEqualToAnchor(scrollView.topAnchor).active = true
stackView.widthAnchor.constraintEqualToAnchor(scrollView.widthAnchor).active = true
Dalmazio
la source
Veuillez ne pas ajouter la même réponse à plusieurs questions. Répondez à la meilleure et marquez les autres comme doublons. Voir Est-il acceptable d'ajouter une réponse en double à plusieurs questions?
FelixSFD
10
Ce ne sont pas vraiment des doublons dans ce cas. L'autre question demande spécifiquement comment le faire par programme alors que celui-ci ne le fait pas. En effet, la première réponse à cette question fournit une méthode graphique pour obtenir le résultat. Néanmoins, une solution programmatique peut être utile à certains utilisateurs.
Dalmazio
9

À jour pour 2020.

100% storyboard OU 100% code.


Voici l'explication la plus simple possible:

  1. Avoir une scène vierge en plein écran

  2. 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.

  3. 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.

  4. 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.

  1. Réglez maintenant le Définissez largeur de chaque UILabel:

    Étonnamment, faites glisser UILabella 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.

Astuce secrète - Bug Apple:

Cela ne fonctionnera pas avec un seul élément! Ajoutez quelques étiquettes pour faire fonctionner la démo.

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:

  1. Étonnamment, définissez la largeur de chaque élément de la vue de pile sur la largeur du grand-parent scrollview ( pas le parent de stackview ).

ou

  1. Étonnamment, définissez une «largeur égale» de la vue de pile à la vue de défilement - même si vous avez quand même les bords gauche et droit de la vue de pile épinglés à la vue de défilement.

Pour être clair, faites UNE de ces méthodes, ne faites PAS les deux.

Fattie
la source
8

Défilement horizontal (UIStackView dans UIScrollView)

Pour le défilement horizontal. Créez d'abord un UIStackViewet un UIScrollViewet ajoutez-les à votre vue de la manière suivante:

let scrollView = UIScrollView()
let stackView = UIStackView()

scrollView.addSubview(stackView)
view.addSubview(scrollView)

Se souvenant de mettre la translatesAutoresizingMaskIntoConstraintsà falsele UIStackViewet UIScrollView:

stackView.translatesAutoresizingMaskIntoConstraints = false
scrollView.translatesAutoresizingMaskIntoConstraints = false

Pour que tout fonctionne, les ancres arrière, avant, supérieure et inférieure UIStackViewdoivent être égales aux UIScrollViewancres:

stackView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
stackView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
stackView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
stackView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true

Mais la largeur de l'ancre UIStackViewdoit être égale ou supérieure à la largeur de l' UIScrollViewancre:

stackView.widthAnchor.constraint(greaterThanOrEqualTo: scrollView.widthAnchor).isActive = true

Maintenant, ancrez votre UIScrollView, par exemple:

scrollView.heightAnchor.constraint(equalToConstant: 80).isActive = true
scrollView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true

scrollView.bottomAnchor.constraint(equalTo:view.safeAreaLayoutGuide.bottomAnchor).isActive = true
scrollView.leadingAnchor.constraint(equalTo:view.leadingAnchor).isActive = true
scrollView.trailingAnchor.constraint(equalTo:view.trailingAnchor).isActive = true 

Ensuite, je suggère d'essayer les paramètres suivants pour l' UIStackViewalignement et la distribution:

topicStackView.axis = .horizontal
topicStackView.distribution = .equalCentering
topicStackView.alignment = .center

topicStackView.spacing = 10

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 UIStackViewtrouve dans un, UIScrollViewvous avez maintenant accès à des encarts de texte pour rendre les choses un peu plus jolies.

let inset:CGFloat = 20
scrollView.contentInset.left = inset
scrollView.contentInset.right = inset

// remember if you're using insets then reduce the width of your stack view to match
stackView.widthAnchor.constraint(greaterThanOrEqualTo: topicScrollView.widthAnchor, constant: -inset*2).isActive = true
sketchyTech
la source
7

Ajoutez simplement ceci à viewdidload:

let insets = UIEdgeInsetsMake(20.0, 0.0, 0.0, 0.0)
scrollVIew.contentInset = insets
scrollVIew.scrollIndicatorInsets = insets

source: https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/LayoutUsingStackViews.html

Rashad.Z
la source
Je ne peux pas vous dire combien cela a sauvé mes malheurs Autolayout + ScrollView. Grande découverte sur ce lien Apple.
déduit le
qu'est-ce que ça fait? Que se passe-t-il sans cela?
Honey
Cela place uniquement le contenu de la vue de défilement sous la barre d'état.
testée
2

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)

import ScrollableStackView

var scrollable = ScrollableStackView(frame: view.frame)
view.addSubview(scrollable)

// add your views with 
let rectangle = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 55))
rectangle.backgroundColor = UIColor.blue
scrollable.stackView.addArrangedSubview(rectangle)
// ...

Exemple de code (Objective-C)

@import ScrollableStackView

ScrollableStackView *scrollable = [[ScrollableStackView alloc] initWithFrame:self.view.frame];
scrollable.stackView.distribution = UIStackViewDistributionFillProportionally;
scrollable.stackView.alignment = UIStackViewAlignmentCenter;
scrollable.stackView.axis = UILayoutConstraintAxisVertical;
[self.view addSubview:scrollable];

UIView *rectangle = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 55)];
[rectangle setBackgroundColor:[UIColor blueColor]];

// add your views with
[scrollable.stackView addArrangedSubview:rectangle]; 
// ...
mgyky
la source
Salut Peter, en fait une excellente idée! Les contributions sont toujours les bienvenues, n'hésitez pas à envoyer une demande de pull pour cela. Meilleur.
mgyky
0

Si vous avez une contrainte pour centrer la vue de pile verticalement à l'intérieur de la vue de défilement, supprimez-la simplement.

Ahmed Elashker
la source
0

Exemple pour une vue de pile / défilement verticale (en utilisant la mise EasyPeasyen page automatique):

let scrollView = UIScrollView()
self.view.addSubview(scrollView)
scrollView <- [
    Edges(),
    Width().like(self.view)
]

let stackView = UIStackView(arrangedSubviews: yourSubviews)
stackView.axis = .vertical
stackView.distribution = .fill    
stackView.spacing = 10
scrollView.addSubview(stackView)
stackView <- [
    Edges(),
    Width().like(self.view)
]

Assurez-vous simplement que la hauteur de chaque sous-vue est définie!

dOM
la source
0
  1. 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.

  2. 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).

  3. 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.

  • Si ce n'est toujours pas le cas, jouez avec la résistance à la compression ou la priorité au contenu.
  • Après cela, ajoutez des contraintes à la vue de la pile.
  • Pensez également à utiliser un UIView vide comme vue de remplissage, si tout ce qui précède ne donne pas de résultats satisfaisants.

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 :).

Nikhil Pandey
la source
0

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]

Configurez une contrainte de largeur égale entre UIStackView et UIScrollView.

entrez la description de l'image ici

Md Imran Choudhury
la source
0

Si quelqu'un cherche un défilement horizontal

func createHorizontalStackViewsWithScroll() {

 self.view.addSubview(stackScrollView)
 stackScrollView.translatesAutoresizingMaskIntoConstraints = false
 stackScrollView.heightAnchor.constraint(equalToConstant: 85).isActive = true
 stackScrollView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
 stackScrollView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true
 stackScrollView.bottomAnchor.constraint(equalTo: visualEffectViews.topAnchor).isActive = true
 stackScrollView.addSubview(stackView)

 stackView.translatesAutoresizingMaskIntoConstraints = false
 stackView.topAnchor.constraint(equalTo: stackScrollView.topAnchor).isActive = true
 stackView.leadingAnchor.constraint(equalTo: stackScrollView.leadingAnchor).isActive = true
 stackView.trailingAnchor.constraint(equalTo: stackScrollView.trailingAnchor).isActive = true
 stackView.bottomAnchor.constraint(equalTo: stackScrollView.bottomAnchor).isActive = true
 stackView.heightAnchor.constraint(equalTo: stackScrollView.heightAnchor).isActive = true

 stackView.distribution = .equalSpacing
 stackView.spacing = 5
 stackView.axis = .horizontal
 stackView.alignment = .fill


 for i in 0 ..< images.count {
 let photoView = UIButton.init(frame: CGRect(x: 0, y: 0, width: 85, height: 85))
 // set button image
 photoView.translatesAutoresizingMaskIntoConstraints = false
 photoView.heightAnchor.constraint(equalToConstant: photoView.frame.height).isActive = true
 photoView.widthAnchor.constraint(equalToConstant: photoView.frame.width).isActive = true

 stackView.addArrangedSubview(photoView)
 }
 stackView.setNeedsLayout()

 }
user1039695
la source
0

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:

Scroll View.Leading = Superview.LeadingMargin
Scroll View.Trailing = Superview.TrailingMargin
Scroll View.Top = Superview.TopMargin
Bottom Layout Guide.Top = Scroll View.Bottom + 20.0
Stack View.Leading = Scroll View.Leading
Stack View.Trailing = Scroll View.Trailing
Stack View.Top = Scroll View.Top
Stack View.Bottom = Scroll View.Bottom
Stack View.Width = Scroll View.Width

entrez la description de l'image ici

code: Stack View.Width = Scroll View.Widthest la clé.

Joshua Cleetus
la source
0

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 UIStackViewpassiez 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.
  • Pendant la transition, UIScrollViewtentera 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 UIScrollViewet son adjustedContentInset, mais à partir de mon journal dans sa layoutSubviewsméthode, je vois le comportement suivant:

  • On agrandit la fenêtre.
  • UIScrollView tente de réduire ses limites (car pas besoin de la zone sous la barre d'outils).
  • UIStackView suit.
  • D'une manière ou d'une autre, il UIScrollViewn'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 que UIScrollView.bounds.height == UIStackView.bounds.height.
  • UIStackView suit.
  • Passez ensuite à l'étape 2.

Il me semble que deux étapes régleraient le problème:

  • Alignez UIStackView.topsur UIScrollView.topMargin.
  • Réglez contentInsetAdjustmentBehaviorsur .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é.

Minsheng Liu
la source