Swift UIScrollView – Mise en œuvre correcte pour le défilement vertical uniquement

En avance, je m'excuse car je dirais que je suis un débutant avec la programmation iOS.

Je veux utiliser UIScrollView car le contenu à afficher dépasse la hauteur de l'écran. Par conséquent, je voudrais seulement un défilement vertical et non un défilement horizontal.

J'utilise le Storyboard pour dessiner les vues avec AutoLayout .

Voici la capture d'écran de mon UIViewController avec UIScrollView :

entrez la description de l'image icientrez la description de l'image ici

Ensuite, je change le label en un gros text comme ça

 override func viewDidLoad() { super.viewDidLoad() self.label1Label.text = "Seize jours après la chute du président Blaise Compaoré, le Burkina Faso a un nouveau chef d'EtatA l'issue d'ultimes tractions, civils et militaires se sont accordés, lundi 17 novembre, sur le nom du diplomate Michel KafandoSeize jours après la chute du président Blaise Compaoré, le Burkina Faso a un nouveau chef d'EtatA l'issue d'ultimes tractions, civils et militaires se sont accordés, lundi 17 novembre, sur le nom du diplomate Michel Kafando" self.label1Label.numberOfLines = 0 self.label1Label.sizeToFit() 

Mon problème est que si je ne définis pas manuellement une largeur pour mon contentView (à l'intérieur du UIScrollView ), le défilement est horizontal, pas vertical. (Regardez la capture d'écran ci-dessous):

entrez la description de l'image ici

J'ai essayé de définir contentSize comme je l'ai vu dans beaucoup de post google mais sans succès:

 self.scrollView.contentSize = CGSizeMake(400.0, 600.0) 

Si je règle manuellement une largeur pour mon contenu ( ie : 320pts ), le défilement sera vertical (GOOD) mais en fonction de la taille de l'iphone, il ne couvrira pas toute la largeur de l'écran comme montré dans la capture d'écran suivante:

entrez la description de l'image ici

La question est: quelle est l'implémentation correcte pour utiliser UIScrollView pour avoir un contentView qui respecte la contrainte autolayout ( full screen : 0top - 0bottom - 0left - 0right ) et le scrolling pour être seulement vertical.

Merci beaucoup pour votre aide!

Mike Woelmer montre comment le faire correctement avec Interface Builder sur le blog Atomic Object.

http://spin.atomicobject.com/2014/03/05/uiscrollview-autolayout-ios/

J'ai aussi mon propre code seulement (pas d'implémentation de storyboard) sur github.

https://github.com/nadthevlad/AutolayotScrollview

Vous ne voulez pas définir la hauteur ou la largeur de votre contenu ou de vos vues. Au lieu de cela, vous souhaitez utiliser les pins et les contraintes Autolayouts pour définir le comportement du scrollview.

  1. Créez votre UIScrollView * scrollView.

  2. Vous voulez créer un UIView * contentView dans lequel vous allez mettre le rest de vos éléments d'affichage.

     [self.view addSubview:scrollView]; [scrollView addSubview:contentView]; [contentView addSubview:_label1]; [contentView addSubview:_label2]; [contentView addSubview:_label3]; [contentView addSubview:_label4]; [contentView addSubview:_label5]; [contentView addSubview:_label6]; 
  3. Pin les 4 bords de scrollView aux 4 bords de self.view

  4. Épinglez les bords supérieur et inférieur de contentView en haut et en bas de scrollView.

  5. C'est la partie difficile. Pour définir le dimensionnement horizontal, vous souhaitez que les bords avant (à droite) et arrière (à gauche) du contenu soient épinglés sur les arêtes de début et de fin self.view au lieu de scrollView. Même si contenView est une vue secondaire de scrollView, ses contraintes horizontales vont atteindre l'extérieur de scrollView et se connecter à self.view.

  6. Épinglez tous les autres éléments de vue à contentView comme vous le feriez normalement.

L'astuce pour autoriser un UIScrollView à défiler dans une seule direction est de faire en sorte que la taille du contenu de UIScrollView pour la dimension restreinte soit la même que la taille de l'image de UIScrollView dans la même dimension. Dans ce cas, scrollview.contentSize.width doit être égal à scrollview.frame.size.width .

Dans cet esprit, essayez ce qui suit:

  1. Assurez-vous que les contraintes sont configurées de la même manière que celle décrite dans cette réponse

  2. Ajoutez le code suivant à votre controller de vue:

     override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews(); self.scrollView.contentSize.height = 3000; // Or whatever you want it to be. } 

Personnellement, je ne suis vraiment pas fan de Auto Layout. Si vous êtes intéressé à essayer ceci sans Auto Layout – ie. juste avec du code au lieu de contraintes – vous pouvez désactiver la layout automatique pour la vue du controller de vue et modifier votre méthode viewWillLayoutSubviews pour ressembler à ceci:

 override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews(); self.scrollView.frame = self.view.bounds; // Instead of using auto layout self.scrollView.contentSize.height = 3000; // Or whatever you want it to be. } 

C'est comme ça que je le fais toujours pour défiler verticalement depuis le storyboard avec des contraintes:

1-faites glisser un viewcontroller

2-faites glisser un scrollview dans la vue principale du controller avec les contraintes L = 0, T = 0, T = 0 et B = 0 à sa vue d'set (vue principale du controller).

3-faites glisser un UIVIew dans la vue de défilement pour travailler comme vue de contenu avec les contraintes L-0, T = 0, T = 0, B = 0 à sa vue d'set (le scrollview)

  • Eh bien ici, il est time de définir la taille du contenu de la vue déroulante, qui contrôle le défilement horizontale et verticale comme suit.

4-pour arrêter le défilement horizontal, faites en sorte que la vue du contenu soit de largeur égale pour faire défiler la vue avec la contrainte.

5-make hauteur de vue du contenu égale hauteur de la vue du controller, Ceci est temporaire jusqu'à ce que nous le remplissons avec un contenu défilant .

6-append des controls dans la vue de contenu jusqu'à la fin.

7-et le plus important supprime la contrainte que vous avez faite au point 5 de la vue haute de contenu et au lieu de cela, faites une contrainte à partir du contrôle en bas de la vue de contenu pour avoir l'alignment du bas. Cela aide à faire en sorte que la vue du contenu commence à partir du premier contrôle en haut et en bas jusqu'au dernier contrôle (tout dépend de cette étape).

8-juste courir et les résultats devraient être comme prévu, sinon s'il vous plaît faites le moi savoir.

J'espère que cela t'aides!

J'utilise cette implémentation uniquement pour les scrollviews horizontaux / verticaux, bien que ce soit en Objective-C, j'essaierai d'expliquer la logique si quelque chose ne vous est pas clair.

 //Getting iDevice's screen width CGRect screenRect = [[UIScreen mainScreen] bounds]; CGFloat screenWidth = screenRect.size.width; //Setting the right content size - only height is being calculated depenging on content. CGSize contentSize = CGSizeMake(screenWidth, HEIGHT_OF_YOUR_CONTENT); self.scrollView.contentSize = contentSize; 

Maintenant, la largeur de la propriété contentSize de la scrollview est attachée à la largeur réelle de l'écran de l'appareil, de sorte que la scrollview défilera uniquement dans la direction verticale.

Grâce à @NadtheVlad, j'ai finalement vu la lumière. Un peu plus de violon m'a appris que contentView doit juste être épinglé au haut, au bas et à la largeur de scrollView. Pas besoin de referencer self.view.

Avec EasyPeasy , c'est simplement:

 scrollView <- Edges() contentView <- [Top(), Bottom(), Width().like(scrollView)]