web-dev-qa-db-fra.com

UIScrollView AutoLayout Vertical uniquement

Je veux que l'AutoLayout fonctionne avec le UIScrollView et j'ai un peu de mal avec. Voici ce que j'ai fait:

  1. Ajoutez un UIScrollView à l'intérieur de la vue principale avec le cadre: [haut: 0, gauche: 0, largeur: 320, hauteur: 568]

  2. Ajoutez UIView "ContentView" à l'intérieur du UIScrollView avec cadre et bgcolor noir: [haut: 0, gauche: 0, largeur: 320, hauteur: 568]

  3. Configuration UIScrollView contraintes: [haut: 0, bas: 0, gauche: 0, droite: 0]

  4. Configuration des contraintes "ContentView": [haut: 0, bas: 0, gauche: 0, droite: 0]

  5. Alignez les éléments dans le "ContentView"

  6. Définissez la vue principale bgcolor sur gris (pour voir ce qui se passe)

Voici une capture d'écran du problème:

Screen Shot1

Pour une raison quelconque, les contraintes font que l'affichage du contenu se trouve au milieu de l'écran. De plus, il défile dans toutes les directions. Je veux que le contenu puisse défiler uniquement dans le sens vertical comme dans UITableView. de sorte que je ne peux pas le déplacer comme ci-dessous:

Screen Shot

Qu'est-ce que je fais mal? J'ai vérifié tous les didacticiels et les réponses que je peux trouver dans StackOverflow et Google, et personne n'a en fait juste un problème bizarre, donc je demande de l'aide.

EDIT: J'ai également ajouté la largeur et la hauteur de ContentView comme contraintes et cela n'a pas aidé non plus.

24
Gasim

Pour désactiver le défilement horizontal, vous pouvez définir la taille du contenu dans la méthode (void) scrollViewDidScroll.

[self.scrollView setContentOffset: CGPointMake(0, self.scrollView.contentOffset.y)];

Vous souhaiterez également définir le verrouillage directionnel de sorte qu'une seule direction de défilement soit utilisée à la fois. https://developer.Apple.com/library/ios/documentation/UIKit/Reference/UIScrollView_Class/index.html#//Apple_ref/occ/instp/UIScrollView/directionalLockEnabled

self.scrollView.directionalLockEnabled = YES;
19
Derek

Vous pouvez le faire entièrement en utilisant des contraintes et c'est vraiment facile.

Le UIScrollView a juste besoin de comprendre la largeur et l'espace qu'il a à l'intérieur. Il doit donc avoir quelque chose d'épinglé aux contraintes Leading, Trailing, Top & Bottom. La largeur et la hauteur du contenu doivent également être fixées (cela ne signifie pas que je dois le préciser. Je peux toujours utiliser des contraintes pour y parvenir.)

  1. Ajoutez un UIScrollView et positionnez comme requis.
  2. Ajoutez un UIView à l'intérieur du UIScrollView pour le contenu.
  3. Définissez les contraintes Leading, Trailing, Top & Bottom du contenu UIView sur 0.
  4. Ajoutez un Equal Width contrainte aux UIScrollView et UIView. Cela le fera défiler verticalement uniquement.
  5. Vous devez maintenant définir la hauteur du contenu UIView. Vous pouvez ensuite spécifier la hauteur de la vue de contenu (blech) ou utiliser la hauteur des contrôles contenus dans celle-ci en vous assurant que le contrôle inférieur est contraint au bas de la vue de contenu.

Je l'ai fait et cela a fonctionné un régal.

36
Chris Kemp

Pour résumer la réponse de Leszek S:

Afin d'avoir une vue à défilement vertical, toutes les vues à l'intérieur de la vue à défilement doivent avoir leurcontrainte de largeur défini. Facile à régler simplement dans la vue d'ensemble de la vue de défilement.

La raison en est que la vue de défilement ne défilera pas horizontalement tant qu’aucune de ses sous-vues n’a besoin de défiler horizontalement. Par exemple, si vous avez une étiquette définie sur 0 ligne, la mise en page automatique tentera de rendre l'étiquette aussi large que possible avant de commencer à ajouter des lignes et des sauts de ligne. S'il n'y a pas de contraintes de largeur explicites sur l'étiquette, cela ne fera qu'élargir la zone de contenu de la vue de défilement. Les contraintes de suivi de la vue de défilement sont ignorées.

Si vous avez un tas de vues, vous voudrez peut-être les mettre dans une seule vue contenant comme dans cette vidéo. Pour mon cas, je n'ai que 5 ou 6 étiquettes qui peuvent changer dynamiquement la hauteur, mais ne devraient jamais changer de largeur, je les ai donc toutes faites de la même largeur que la vue de défilement. Et bingo, vue à défilement vertical avec des étiquettes qui grandissent ou rétrécissent selon le texte.

7
n13

J'ai écrit une fonction qui permet de faire défiler le contenu verticalement mais pas horizontalement. Il crée une UIView avec une largeur limitée à l'intérieur de scrollview et y incorpore toutes les sous-vues de scrollview.

TegScrolledContent.createContentView(scrollView)

https://github.com/exchangegroup/scrollable-content-ios

enter image description here

3
Evgenii

Avec la réponse de @ derek, je voudrais ajouter que la définition de contentOffset toujours dans scrollViewDidScroll entraînera un problème de performances. Veuillez donc vérifier uniquement si x n'est pas 0, puis définissez contentOffset

    if(contentOffset.x != 0){
        setContentOffset(CGPointMake(0, contentOffset.y), animated: false)
    }

et oui à la scrollview

directionalLockEnabled = true
1
sheetal

Donner à la vue du contenu des contraintes de hauteur et de largeur explicites

1
mustafa

Vous trouverez ci-dessous un extrait que j'ai utilisé pour obtenir une vue de défilement vertical uniquement. Il fonctionne en ajoutant une vue de contenu en tant que vue enfant d'une vue de défilement, puis en contraignant la largeur de cette vue de contenu à la largeur de la vue de défilement parent. À partir de là, toutes les sous-vues doivent être ajoutées à la vue de contenu plutôt qu'à la vue de défilement.

// View that will contain content of scroll view. Width is constrained to the width of the scroll view.
UIView *contentView = [[UIView alloc] init];
contentView.translatesAutoresizingMaskIntoConstraints = NO;
[scrollView addSubview:contentView];

views[@"contentView"] = contentView;
[scrollView addConstraint:[NSLayoutConstraint constraintWithItem:contentView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0.0]];
[scrollView addConstraint:[NSLayoutConstraint constraintWithItem:contentView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:scrollView attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0]];
[scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[contentView]|" options:0 metrics:nil views:views]];

// Now, add all your subviews to contentView
1
josh-fuggle