web-dev-qa-db-fra.com

UIStackView - Répartissez uniformément les vues depuis le centre

J'ai un UIStackView, à l'intérieur d'un UIScrollView pour montrer les sous-vues ajoutées dynamiquement disposées horizontalement. La solution actuelle commencera à afficher les éléments à partir de la gauche, je voudrais commencer à distribuer les éléments à partir du centre sans modifier la largeur et la hauteur des sous-vues. Comment je fais ça? Je suis également ouvert aux solutions qui n'utilisent pas également UIStackView. De cette façon, je pouvais prendre en charge les appareils <iOS9.

Curent

( Courant )

Expected

( Attendu )

27
Ajith

Réponse courte:

Contraintes ScrollView

Leading >= 0, Trailing >= 0, Top >= 0, Bottom >= 0
Center X  and Center Y 

Contraintes StackView

Leading = 0, Trailing = 0, Top = 0, Bottom = 0
StackView width = ScrollView width (priority low :250)
StackView height = ScrollView height

Réponse longue

Tout d'abord, votre structure est bonne, nous avons:

UIScrollView
     UIStackView (horizontal)
         Subviews 

Donc, pour atteindre l'objectif, nous devons:

  • Centrez le UIScrollView
  • Définissez le contentSize du UIScrollView égal à la taille intrinsèque du contenu du UIStackView

Voici comment faire :

Étape 1: Centrez le cadre de UIScrollView

enter image description here

CenterY et CenterX contraintes utilisées pour centrer le cadre du UIScrollView

Leading Space> = 0, Trailling Space> = 0, Top Space> = 0, Bottom Space> = 0 sont utilisés pour empêcher le cadre de l'UIScrollView de dépasser le cadre de la vue parent

J'ai utilisé la taille intrinsèque de l'espace réservé pour ne pas afficher les erreurs liées au contentSize du UIScrollView (car nous n'avons pas encore les sous-vues donc le contentSize).

Maintenant, le cadre de notre UIScrollView est OK, passez à l'étape suivante :)

Étape 2: ajoutez le UIStackView horizontal

enter image description here

  • Les contraintes Top, Bottom, Leading, Trailing sont utilisées pour corriger le cadre UIStackView
  • Hauteur égale et largeur égale utilisées pour calculer le contentSize de UIScrollView

PS. Tout changement dans le cadre de l'UIStackView, changez le contentSize de l'UIScrollView

Étape 3: ajouter des sous-vues

Parce que nous utilisons Fill Distribution dans le UIStackView tous les subviews doivent avoir une taille de contenu intrinsèque (ou des contraintes de hauteur et de largeur (non préférées)). Par exemple, si nous utilisons Fill Equally, un seul subview avec une taille de contenu intrinsèque (ou des contraintes de hauteur et de largeur (non préférées)) suffisantes, les autres tailles de sous-vues seront égales à celle-ci.

Par exemple: je vais ajouter 3 étiquettes (veuillez supprimer la taille intrinsèque de l'espace réservé du UIScrollView)

enter image description here

Ça marche !! non, non, pas encore essayer d'ajouter les quatrième et cinq étiquettes :)

Pourquoi?

Pour comprendre, nous allons calculer le cadre de chaque élément de la vue avec deux exemples:

Taille de la vue parent: 200, 200 Taille du contenu intrinsèque de la première étiquette: 120, 50 Taille du contenu intrinsèque de la deuxième étiquette: 150, 50

Premier exemple (uniquement la première étiquette dans le UIStackView)

  • UIStackView taille du contenu intrinsèque = 120, 50
  • UIScrollView contentSize = 120, 50
  • UIScrollView frame = 40, 75, 120, 50

Tous les cadres sont OK

Deuxième exemple (avec les deux étiquettes)

  • UIScrollView frame = 0, 0, 200, 50
  • UIScrollView contentSize = 200, 50
  • UIStackView taille du contenu intrinsèque = 200, 50

Ainsi, le UIStackView ne peut pas afficher correctement les deux étiquettes (car la largeur de UIStackView inférieure à la largeur des deux étiquettes), et nous n'avons pas le défilement parce que, le UIStackView la largeur de la contrainte est égale à la largeur UIScrollView. Cela fonctionne lorsque la taille de contenu intrinsèque UIStackView est inférieure à la trame max UIScrollView.

Pour résoudre ce problème, nous changeons la priorité de la contrainte de largeur en une valeur inférieure à la valeur de priorité de taille de contenu intrinsèque UIStackView, et tout fonctionne bien :)

enter image description here

J'espère que cela pourra aider.

source de code

28
Hamza