Comment utiliser UIScrollView dans Storyboard

125

J'ai une vue de défilement avec un contenu de 1000 pixels de haut et j'aimerais pouvoir le mettre en page pour une conception facile sur le storyboard.
Je sais que cela peut être fait par programmation, mais je veux vraiment pouvoir le voir visuellement. Chaque fois que je mets une vue de défilement sur un contrôleur de vue, elle ne défile pas. Est-il possible de le faire fonctionner comme je le souhaite ou dois-je le faire dans le code?

Alex Reynolds
la source
1
Salut à tous, veuillez consulter les commentaires ci-dessous pour découvrir de nouvelles façons de procéder. J'ai écrit ceci il y a 2 ans et xCode a beaucoup changé. Il existe d'autres moyens de le faire maintenant, alors soyez conscient. Solutions iOS 7 et iOS 8 suggérées dans les commentaires
Alex Reynolds
Voici à nouveau 2 ans plus tard des commentaires sur la façon dont cela ne fonctionne pas ou la mise en page automatique est meilleure. La question initiale était de savoir comment le faire dans iOS 5/6. Je n'utilise que la mise en page automatique ces jours-ci pour cela, vous devriez / pouvez aussi. Consultez les réponses sur la mise en page automatique pour obtenir de l'aide. Veuillez voter pour les réponses de mise en page automatique si elles sont utiles. Merci à tous
Alex Reynolds

Réponses:

149

Je réponds à ma propre question car je viens de passer 2 heures à trouver la solution et StackOverflow permet ce style de contrôle qualité.

Commencez à terminer voici comment le faire fonctionner dans le storyboard.

1: allez à votre vue contrôleur et cliquez sur Attribute Inspector.

2: remplacez Taille par Freeforminférée.

3: Accédez à la vue principale de ce storyboard, pas à votre vue de défilement mais plutôt à la vue de niveau supérieur.

4: Cliquez Size Inspectoret définissez cette vue à la taille souhaitée. J'ai changé ma taille à 1000.

Vous verrez maintenant que votre storyboard a votre configuration de vue afin que vous puissiez voir toute la hauteur de votre parchemin pour une conception facile.

5: Déposez une vue de défilement et étirez-la pour qu'elle occupe toute la vue. Vous devriez maintenant avoir une vue de défilement avec une taille de 320,1000 assis sur une vue dans votre contrôleur de vue.

Nous devons maintenant le faire défiler et lui faire afficher correctement le contenu.

6: Cliquez sur votre scrollview et cliquez sur Identity Inspector.

7: Ajoutez un User Defined runtime attributeavec KeyPath du contentSizetype de SIZE et entrez la taille de votre contenu. Pour moi, c'est (320, 1000).

Puisque nous voulons voir toute notre vue de défilement sur le storyboard, nous l'avons étirée et il a une image de 320,1000, mais pour que cela fonctionne dans notre application, nous devons changer le cadre pour ce que sera la vue de défilement visible.

8: Ajoutez un runtime attributeavec KeyPath frameavec le type RECT et 0,0,320,416.

Maintenant, lorsque nous exécutons notre application, nous aurons une vue de défilement visible avec un cadre de 0,0,320, 416 et pouvons faire défiler jusqu'à 1000. Nous sommes en mesure de mettre en page nos sous-vues et images et autres dans Storyboard exactement comme nous voulons qu'elles apparaissent. Ensuite, nos attributs d'exécution s'assurent de l'afficher correctement. Tout cela sans 1 ligne de code.

Alex Reynolds
la source
5
Si vous utilisez correctement la fonction de dimensionnement automatique de la vue par défilement, vous n'avez pas besoin de définir l' frameattribut. En effet, tous les appareils n'ont pas exactement la même taille (iPhone 5).
Tronix117
Tronix117, alors comment résolvez-vous ce problème sans cet attribut?
Andras Hatvani
2
Si vous avez une solution pour iOS 7, faites-le moi savoir. Cette réponse a été publiée il y a plus d'un an avant iOS 7. Je suis submergé ou je mettrais à jour ceci pour iPhone5 et ios7
Alex Reynolds
2
REMARQUE: La solution pour POUR iOS7 est en dessous de stackoverflow.com/a/22489795/1553014
Raja Rao
1
Remarque: pour iOS 8.3 XCode 6.3, la réponse est ici: stackoverflow.com/questions/26742230/…
T.Coutlakis
51

Voici les étapes Auto Layoutqui ont fonctionné pour moi sur XCode 8.2.1.

  1. Sélectionnez Size Inspectorde View Controlleret changer Simulated Sizeà Freeformhauteur 1000 au lieu de Fixed.
  2. Renommez la vue View Controlleren RootView .
  3. Faites glisser une Scroll Viewsous-vue de RootView et renommez-la ScrollView .
  4. Ajoutez des contraintes pour ScrollView :
    • ScrollView [Top, Bottom, Leading, Trailing] = RootView [Top, Bottom, Leading, Trailing]
  5. Faites glisser un Vertical Stack Viewcomme sous - vue ScrollView et renommer comme ContentView .
  6. Ajoutez des contraintes pour ContentView :
    • ContentView .height = 1000
    • ContentView [haut, bas, interligne, fin, largeur] = ScrollView [haut, bas, interligne, fin, largeur]
  7. Sélectionnez Attributes Inspectordes ContentView et changer Distributionà la Fill Equallyplace de Fill.
  8. Faites glisser un Viewcomme sous - vue ContentView et renommer comme Redview .
  9. Définir Redcomme arrière-plan de RedView .
  10. Faites glisser un Viewcomme sous - vue ContentView et renommer comme BlueView .
  11. Définir Bluecomme arrière-plan de BlueView .
  12. Sélectionnez RootView et cliquez sur le Update Framesbouton.
    • Update Framesest un nouveau bouton dans Xcode8, au lieu d'un Resolve Auto Layout Issuesbouton. Cela ressemble à un bouton d'actualisation, situé dans la barre de contrôle sous le Storyboard: Bouton Mettre à jour les cadres

Afficher la hiérarchie:

  • RootView
    • ScrollView
      • ContentView
        • RedView
        • BlueView

Voir la scène du contrôleur (hauteur: 1000):

scène

Exécuter sur iPhone7 (Hauteur: 1334/2):

démo

jqgsninimo
la source
J'ai le même problème et je me demande si cela fonctionnerait lorsque mon scrollview n'a pas la taille de rootview?
GalaxyVintage
Mais le fait est qu'il y aura un espace vide en bas pour l'ipad
G.Abhisek
Une note pour le réglage BlueViewde haut en RedViewbas pour les débutants comme moi (Xcode 8.2): 1) Faites glisser ce qui BlueView suit RedView (c'est-à-dire qu'ils ne doivent pas se chevaucher ou l'étape 4) ne fonctionnera pas). 2) Ouvrez le menu des broches en bas. 3) Cliquez sur la petite flèche à droite de la contrainte de marge supérieure. 4) Sélectionnez RedViewdans ce menu et définissez la valeur sur 0. Ceci est différent des versions précédentes de Xcode où vous pouviez faire des choses comme Editor-> Pin-> ...
Krøllebølle
juste curieux, pourquoi utilisez-vous une vue de pile verticale au lieu d'un UIView normal?
Changerrs
@Changerrs que j'utilise UIStackViewpour éviter la peine de fixer des contraintes.
jqgsninimo
43

Voici les étapes qui ont fonctionné pour moi sur iOS 7 et XCode 5.

  1. Faites glisser un ViewController (il est livré avec UIView "View").

    1.1 Sélectionnez "View Controller" et sélectionnez "File Inspector" et décochez "Auto layout".

  2. Faites glisser un ScrollView (en tant qu'enfant de l'UIView "View" de ViewController)
  3. Sélectionnez ScrollView et ouvrez "Identity Inspector".
  4. Entrez "contentSize" pour keyPath. Sélectionnez "Taille" pour le type. Et entrez {320, 1000} comme valeur.

    Remarque: l'étape 4 indique simplement que la molette contient du contenu dont la taille est de 320x1000 unités. Ainsi, la définition de contentSize fera fonctionner le défilement.

  5. Sélectionnez View Controller, sélectionnez "Attributes Inspector" puis sélectionnez Freeform dans Size.

    Remarque: l'étape 5 nous permettra de modifier la taille de "Vue" fournie avec le contrôleur de vue.

  6. Sélectionnez "Affichage", puis sélectionnez "Inspecteur de taille".

  7. Définissez la largeur sur 320 et la hauteur sur 1000.

Remarque: 5, 6 et 7 est purement pour nous de voir une vue étirée ou entièrement développée dans StoryBoard. Remarque: assurez-vous de désélectionner "Mise en page automatique" sur View Controller.

Votre hiérarchie de vues doit ressembler à ceci: hiérarchie

Raja Rao
la source
3
Cette technique fonctionne toujours à partir de Xcode 6.1 et iOS 8.1.
Chris Harris
1
Incroyable. Merci pour cela. Fonctionne définitivement sur Xcode 6.1 et iOS 8.1 comme mentionné.
Shanker Kaura
45
Ok ... alors que faire si nous avons BESOIN d'autolayout?
PostCodeism
1
Mutch meilleure réponse .. Merci!
StefMa
1
Solution pour iOS 8 Mise en page automatique et classe de taille stackoverflow.com/questions/26742230/…
jithin
13

Après des heures d'essais et d'erreurs, j'ai trouvé un moyen très simple de mettre du contenu dans des vues de défilement qui sont `` hors écran ''. Testé avec XCode 5 et iOS 7. Vous pouvez le faire presque entièrement dans Storyboard, en utilisant 2 petites astuces / solutions de contournement:

  1. Faites glisser un contrôleur de vue sur votre storyboard.
  2. Faites glisser un scrollView sur ce viewController, pour la démonstration, vous pouvez laisser sa taille par défaut, couvrant tout l'écran.
  3. Vient maintenant l' astuce 1 : avant d'ajouter un élément à la scrollView, faites glisser dans une `` vue '' régulière (Cette vue sera rendue plus grande que l'écran, et contiendra tous les sous-éléments comme des boutons, des étiquettes, ... appelons-la le ' vue englobante ').
  4. Soit la taille Y de cette vue englobante dans l'inspecteur de taille par exemple 800.
  5. Déposez une étiquette sur la vue englobante, quelque part à la position Y 200, nommez-la «étiquette 1».
  6. Astuce 2 : assurez-vous que la vue englobante est sélectionnée ( pas la scrollView! ), Et définissez sa position Y sur par exemple -250, afin que vous puissiez ajouter un élément `` en dehors '' de l'écran
  7. Déposez une étiquette, quelque part en bas de l'écran, nommez-la «étiquette 2». Cette étiquette est en fait «hors écran».
  8. Réinitialisez la position Y de la vue englobante sur 0, vous ne verrez plus l'étiquette 2, car elle était positionnée hors de l'écran.

Jusqu'à présent, pour le travail du storyboard, vous devez maintenant ajouter une seule ligne de code à la méthode 'viewDidLoad' de viewController pour définir le contenu de scrollViews afin qu'il contienne toute la 'vue englobante'. Je n'ai pas trouvé de moyen de le faire dans Storyboard:

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.scrollView.contentSize = CGSizeMake(320, 800);
}

Vous pouvez essayer de le faire en ajoutant un contentSizekeyPath en tant quesize au scrollView dans l'inspecteur d'identité et en le définissant sur (320, 1000).

Je pense qu'Apple devrait rendre cela plus facile dans le storyboard, dans un TableViewController, vous pouvez simplement faire défiler hors écran dans Storyboard (ajoutez simplement 20 cellules, et vous verrez que vous pouvez simplement faire défiler), cela devrait être possible avec un ScrollViewController aussi.

Ronny Webers
la source
1
c'est correct jaxvy, lorsque j'ai récemment porté mon application pour prendre en charge la mise en page automatique, j'ai remplacé la vue de défilement par une vue de table statique. Fait le même travail et présente également des avantages supplémentaires.
Ronny Webers
Qu'en est-il de changer le contenu de manière dynamique, car tous les iPhones sont livrés avec des tailles différentes
Veeresh Kumbar
8

Faire fonctionner le défilement dans iOS7 et la mise en page automatique dans iOS 7 et XCode 5.

En plus de cela: https://stackoverflow.com/a/22489795/1553014

Apparemment, tout ce que nous devons faire est:

  1. Définissez toutes les contraintes sur Scroll View (c.-à-d. Fixez d'abord la vue de défilement)

  2. Ensuite, définissez la contrainte distance-from-scrollView sur l'élément le plus bas pour faire défiler la vue (qui est la super vue).

Remarque: l'étape 2 indiquera au storyboard où se trouve le dernier élément de contenu dans la vue Défilement.

Raja Rao
la source
7

Pour cet exemple, j'ai décoché la fonction Autolayout du générateur d'interface. Et j'utilise toujours (sans aucune raison) la version 4.6.1 relativement ancienne de Xcode.

Commencez avec un contrôleur de vue qui a une vue de défilement dessus (la vue principale).

1: Ajoutez une vue de conteneur, de la bibliothèque d'objets, à la vue de défilement. Notez qu'un nouveau contrôleur de vue est ajouté au storyboard et qu'il est lié au contrôleur de vue avec la vue de défilement.

2: Sélectionnez la vue du conteneur et, dans l'inspecteur de taille, ancrez-la en haut et à gauche sans redimensionnement automatique.

entrez la description de l'image ici

3: remplacez sa hauteur par 1 000. (1 000 est utilisé dans cet exemple. Vous devez appliquer la valeur souhaitée.)

4: Sélectionnez le nouveau contrôleur de vue et, dans l'inspecteur d'attributs, changez Taille en Forme libre.

entrez la description de l'image ici

5: Sélectionnez la vue du nouveau contrôleur de vue et, dans l'inspecteur de taille, modifiez la hauteur à 1000 (qui est égale à la hauteur de la vue du conteneur).

6: Pour votre test plus tard, tout en restant sur la vue du nouveau contrôleur de vue, ajoutez une étiquette en haut et en bas de la vue.

7: Sélectionnez la vue de défilement dans le contrôleur de vue d'origine. Dans l'inspecteur d'identité, ajoutez un attribut avec le keyPath défini sur contentSize, le type défini sur Size et la valeur définie sur {320, 1000} (ou la taille de la vue de votre conteneur).

entrez la description de l'image ici

8: Exécutez sur le simulateur iPhone 4 pouces. Vous devriez pouvoir faire défiler de l'étiquette supérieure à l'étiquette inférieure.

9: Exécutez sur le simulateur iPhone 3,5 pouces. Vous devriez pouvoir faire défiler de l'étiquette supérieure à l'étiquette inférieure.

N'oubliez pas que Xcode 4.6.1 ne peut être construit que pour iOS6 et les versions antérieures. En utilisant cette approche et en construisant pour iOS6, je suis toujours en mesure d'obtenir les mêmes résultats lorsque l'application est exécutée sur iOS7.

yoninja
la source
5

Notez que dans un UITableView, vous pouvez en fait faire défiler la vue du tableau en sélectionnant une cellule ou un élément et en faisant défiler vers le haut ou vers le bas avec votre trackpad.

Pour un UIScrollView, j'aime la suggestion d'Alex, mais je recommanderais de changer temporairement le contrôleur de vue en forme libre, d'augmenter la hauteur de la vue racine, de créer votre interface utilisateur (étapes 1 à 5), puis de la remettre à la taille standard déduite lorsque vous avez terminé afin que vous n'ayez pas à coder en dur les tailles de contenu en tant qu'attributs d'exécution. Si vous faites cela, vous vous exposez à de nombreux problèmes de maintenance en essayant de prendre en charge les appareils 3,5 "et 4", ainsi qu'à la possibilité d'augmenter les résolutions d'écran à l'avenir.

Kyle Clegg
la source
4

Vous ne devez définir la propriété contentSize que sur viewDidAppear, comme cet exemple:

- (void)viewDidAppear:(BOOL)animated{

     [super viewDidAppear:animated];
     self.scrollView.contentSize=CGSizeMake(306,400.0);

}

Il résout les problèmes de mise en page automatique et fonctionne correctement sur iOS7.

Lucio Fonseca
la source
REMARQUE: Alex Zavatone propose une autre façon de définir contentSize, sans écrire de code.
ToolmakerSteve
4

Clause de non-responsabilité: - Uniquement pour ios 9 et supérieur (Stack View).

Si vous déployez votre application sur des appareils iOS 9, utilisez une vue de pile . Voici les étapes: -

  1. Ajouter une vue de défilement avec des contraintes - épingler à gauche, à droite, en bas, en haut (sans marges) pour superview (vue)
  2. Ajoutez une vue de pile avec les mêmes contraintes pour faire défiler la vue.
  3. Stack View Autres contraintes: - stackView.bottom = view.bottom et stackView.width = scrollView.width
  4. Commencez à ajouter vos vues. La vue de défilement décidera de faire défiler en fonction de la taille de la vue de pile (qui est essentiellement votre vue de contenu)
DharinS
la source
1
Il s'agit d'une technique utile qui minimise le nombre de contraintes que vous devez ajouter manuellement. En général, la manière d'obtenir le défilement consiste à s'assurer qu'il existe des contraintes suffisantes pour la mise en page automatique pour calculer la taille du contenu. La vue Stack fait une grande partie de cette contrainte pour vous. Définissez la pile spacingpour mettre de l'espace entre les sous-vues (enfants). Si vous avez besoin de plus d'espace entre seulement deux sous-vues, ajoutez un enfant "spacer": un UIView transparent de taille fixe.
ToolmakerSteve
4

Dans iOS7, j'ai trouvé que si j'avais une vue dans un UIScrollView sur un ViewController de taille FreeForm, elle ne défilerait pas dans l'application, peu importe ce que je faisais. J'ai joué et j'ai trouvé que ce qui suit semblait fonctionner, qui n'utilise pas de FreeForms:

  1. Insérer un UIScrollView dans la vue principale d'un ViewController

  2. Définissez les contraintes de mise en page automatique sur le ScrollView comme il convient. Pour moi, j'ai utilisé le guide de mise en page 0 vers le haut et le guide de mise en page 0 vers le bas

  3. À l'intérieur de ScrollView, placez une vue de conteneur. Réglez sa hauteur sur ce que vous voulez (par exemple 1000)

  4. Ajoutez une contrainte de hauteur (1000) au conteneur pour qu'il ne soit pas redimensionné. Le bas sera passé la fin du formulaire.

  5. Ajoutez la ligne [self.scrollView setContentSize: CGSizeMake (320, 1000)]; au ViewController qui contient le scrollView (que vous avez connecté en tant qu'IBOutlet)

Le ViewController (ajouté automatiquement) qui est associé au conteneur aura la hauteur souhaitée (1000) dans Interface Builder et défilera également correctement dans le contrôleur de vue d'origine. Vous pouvez maintenant utiliser ViewController du conteneur pour mettre en page vos contrôles.

nh32rg
la source
J'ai voté pour cette réponse parce que j'aime la technique; Cependant, je pense que vous vous trompez sur le fait que FreeForm VC interfère avec le défilement, quelle que soit la version d'iOS. A commencer par iOS 6 (qui a ajouté la mise en page automatique), un ensemble complet de contraintes, comme indiqué dans d' autres réponses, va défiler. Je ne pense pas que FreeForm interfère avec cela (même si je ne l'ai pas essayé). Il vous manquait peut-être une contrainte non évidente; ScrollView + AutoLayout est un peu un hack.
ToolmakerSteve
3

Je veux mettre mes 5 cents à la réponse acceptée: j'ai fait des recherches sur le sujet pendant 2 jours et j'ai finalement trouvé une solution que j'utiliserai toujours à partir de maintenant

aller au point 4 dans la réponse acceptée et oublier d'ajouter des attributs de cadres et de tailles de contenu, etc.

pour tout rendre automatique, utilisez simplement la solution de ce lien

tout est clair, facile, élégant et fonctionne comme un charme sur ios 7. je suis plutôt content de tout ça lol

jungle_mole
la source
lien mis à jour
ToolmakerSteve
votre solution (si vous suivez votre lien jusqu'à la fin) consiste à ajouter une ligne de code, donc ce n'est pas particulièrement conforme à la question - en utilisant uniquement le storyboard
Boris Gafurov
@BorisGafurov n'est-il pas un peu obsolète avec ios7 de toute façon. et mb ce n'est pas en ligne, mais je suis sûr que cela a aidé quelques personnes de toute façon .. alors laissez-le être
jungle_mole
3

Voici une solution simple.

  1. Définissez l'attribut de taille de votre contrôleur de vue dans le storyboard sur "Freeform" et définissez la taille souhaitée. Assurez-vous qu'il est suffisamment grand pour s'adapter au contenu complet de votre vue de défilement.

  2. Ajoutez votre vue de défilement et définissez les contraintes comme vous le feriez normalement. c'est-à-dire si vous voulez que la vue de défilement ait la taille de votre vue, attachez vos marges supérieure, inférieure, de début et de fin à la vue de surveillance comme vous le feriez normalement.

  3. Maintenant, assurez-vous simplement qu'il existe des contraintes dans les sous-vues de la vue de défilement qui relient le haut et le bas de la vue de défilement. Idem pour la gauche et la droite si vous avez un défilement horizontal.

entrez la description de l'image ici

Hulk_SMASH
la source
2

Voici une réponse un peu sale qui aboutit à la même solution pour les vues de défilement vertical, mais (contrairement à l'éthique de stackoverflow) ne répond pas à la question. Au lieu d'utiliser un scrollView, utilisez simplement un UITableView, faites glisser un UIView normal dans l'en-tête et rendez-le aussi grand que vous le souhaitez, vous pouvez maintenant faire défiler le contenu dans le storyboard.

TimWhiting
la source
À mon humble avis, c'est une bonne réponse, pas contre l'éthos de stackoverflow, de suggérer une approche alternative (à moins qu'OP ne dise spécifiquement qu'ils doivent le faire comme ils le demandent.) Et la plus grande valeur de stackoverflow est d'aider toutes les autres personnes qui se présentent. et lisez les questions et réponses. :)
ToolmakerSteve
0

Apparemment, vous n'avez pas du tout besoin de spécifier la hauteur! Ce qui est génial si cela change pour une raison quelconque (vous redimensionnez les composants ou changez la taille des polices).

Je viens de suivre ce tutoriel et tout a fonctionné: http://natashatherobot.com/ios-autolayout-scrollview/

(Note latérale: il n'est pas nécessaire d'implémenter viewDidLayoutSubviews sauf si vous souhaitez centrer la vue, la liste des étapes est donc encore plus courte).

J'espère que cela pourra aider!

Lukasz Czerwinski
la source
0

La clé est le contentSize.

Ceci est souvent manquant et non indiqué lors de l'ajout d'un UIScrollView.

Sélectionnez UIScrollView et sélectionnez l'inspecteur d'identité.

Ajoutez un contentSizekeyPath en tant que sizeà scrollView dans l'inspecteur d'identité et définissez-le sur (320, 1000).

Faites défiler.

Alex Zavatone
la source
C'est une approche, et je l'ai moi-même utilisée. Cependant, je ne considère pas que ce soit l'approche préférée. Il est "plus propre / plus flexible" de fournir un ensemble complet de contraintes, de sorte que la mise en page automatique puisse calculer elle-même la taille du contenu. Trois alternatives: des contraintes de haut en bas , ou utiliser la vue de la pile , ou contraindre à la position de l'élément du bas .
ToolmakerSteve
0

Si vous utilisez la mise en page automatique, la meilleure approche consiste à utiliser UITableViewController avec des cellules statiques dans le storyboard.

J'ai également rencontré une fois le problème avec une vue qui nécessite beaucoup plus de défilement, alors changez UIScrollView avec la technique mentionnée ci-dessus.

Usman Awan
la source
0

Voici comment configurer une vue de défilement à l'aide de Xcode 11

1 - Ajouter une vue de défilement et définir des contraintes de haut, de bas, de début et de fin

entrez la description de l'image ici

2 - Ajoutez une vue de contenu à la vue de défilement, faites glisser une connexion vers le Guide de mise en page du contenu et sélectionnez En tête, En haut, en bas et à la fin. Assurez-vous de définir ses valeurs sur 0 ou sur les constantes souhaitées.

entrez la description de l'image ici

3 - Faites glisser de la vue de contenu vers le guide de disposition du cadre et sélectionnez largeurs égales

entrez la description de l'image ici

4 - Définissez une constante de contrainte de hauteur dans la vue de contenu

JP Aquino
la source