web-dev-qa-db-fra.com

comment utiliser UIScrollView dans Interface Builder?

Bien que j'aie utilisé UIScrollView avec succès par le passé en le manipulant par programme, je ne parviens pas à le faire fonctionner en le configurant exclusivement dans Interface Builder. 

J'ai une simple page "à propos de" dans mon application iPhone. Il a une UITextView, des icônes et des liens vers mes autres applications. J'ai ajouté toutes ces vues à ma UIScrollView, en les organisant de manière à ce que leur taille totale soit> 480. Lorsque je lance mon application, la vue de défilement affiche uniquement le contenu qui convient à l'écran, et aucun défilement.

Est-il possible de le faire entièrement via IB ou dois-je manipuler le contentSize via le code?

94
George Armhold

Vous avez oublié de définir la propriété contentSize de UIScrollView. Curieusement, vous ne pouvez pas le faire depuis Interface Builder. Vous devrez le faire à partir du contrôleur de vue gérant cette vue de défilement.

130
Stefan Arentz

La réponse de Boby_Wan m'a fait réfléchir et j'ai trouvé la solution suivante pour configurer le contentSize d'UIScrollView à partir d'Interface Builder:

  1. Sélectionnez la UIScrollView dans la scène Storyboard
  2. Accédez à la inspecteur d'identité, créez un nouvel attribut d'exécution défini par l'utilisateur (cliquez sur le bouton +).
  3. Remplacez l’attribut Chemin de la clé par contentSize
  4. Remplacez l’attribut Type par Size
  5. Maintenant, définissez Valeur sur { largeur du contenu souhaité , hauteur du contenu souhaitée }

par exemple, définir la valeur sur {320, 920} permettra à l'utilisateur de faire défiler tout un écran supplémentaire sur l'iPhone.

(J'utilise xcode 4.3.3, le projet cible de déploiement iOS est 5.1)

Lorsque j'ai fait cela pour la première fois, j'ai reçu l'erreur suivante:

Configuration illégale: 
Attributs d'exécution définis par l'utilisateur de type taille avec des versions de Xcode antérieures à 4.3
MainStoryboard.storyboard

Si vous rencontrez également cette erreur, la solution est simple: sélectionnez le Storyboard dans le Navigateur de projet, puis ouvrez le Inspecteur de fichiers. Recherchez/développez la section Interface Builder Document et vous trouverez une liste déroulante pour Développement. Assurez-vous que ceci est défini sur Xcode 4.3

113
Herr Grumps

Avec Autolayout (iOS6 +), vous pouvez éviter de définir contentSize. Définissez les contraintes suivantes à la place:

  1. Épinglez le haut de la vue à défiler en haut de son enfant le plus haut.
  2. Et épinglez le bas au bas de son enfant le plus bas.
24
Danyal Aytekin

Vous pouvez le faire en utilisant uniquement Interface Builder, accédez à l'inspecteur d'identité (troisième onglet de l'inspecteur) et ajoutez un attribut new User Defined Runtime avec 

  • Chemin de la clé: contentSize
  • Type: Taille 
  • Valeur: {largeur, hauteur}
18
Anton Banchev

Il existe maintenant un moyen de faire défiler une UIScrollView sans quitter Storyboard

  1. Sélectionnez la UIScrollView dans le storyboard, accédez à la inspecteur de la taille Et modifiez la valeur en bas (ou toute autre valeurvous devez changer) dans la Inserts de contenu section à la hauteur de la zone de contenu. 
  2. Allez maintenant dans inspecteur d'identité et créez un nouvel attribut d'exécution défini par l'utilisateur (en cliquant sur le bouton +) et nommez-le contentSize. Peu importe ce que vous remplissez Type ou Valeur (vous pouvez même laisser leur valeur par défaut).

Cela fera fonctionner correctement la UIScrollView, bien que je ne sache pas pourquoi la deuxième étape est nécessaire (j'ai découvert par hasard). :(

14
RoberRM

une approche que j'ai utilisée par le passé consiste à faire glisser la vue de défilement de sa vue contenant dans le générateur d'interface et à définir sa taille réelle sur le contenu souhaité.

ce qui n'est pas intrinsèquement évident à propos du générateur d'interface est que vous pouvez avoir des vues non associées qui sont stockées dans le nib, mais ne font pas partie de la vue principale à laquelle le nib est principalement destiné. 

dans la vue où vous voulez que le scrollview vive, placez un simple UIView, que vous utiliserez comme substitut. (C’est simplement pour vous permettre de concevoir visuellement son emplacement. Si vous n’utilisez que la vue entière, vous pouvez ignorer cette étape et utiliser le deuxième extrait de code que j’ai fourni à la fin de cette réponse).

vous pouvez ensuite remplir la vue à défiler avec des contrôles, en la présentant visuellement comme vous le souhaitez. attribuez les propriétés d'espace réservé et de scrollview à l'intérieur de votre contrôleur de vue pour pouvoir y accéder au moment de l'exécution.

au moment de l'exécution, dans - (void) viewDidLoad 

scrollView.contentSize = scrollView.frame.size;
scrollView.frame = placeholder.frame;
[placeholder.superview addSubView:scrollView];
[placeholder removeFromSuperview];

alternativement (si vous n'avez pas utilisé d'espace réservé):

CGRect f = self.view.frame;
scrollView.contentSize = f.size;
f.Origin.x = 0;
f.Origin.y = 0;
scrollView.frame = f;
[self.view addSubView:scrollView];

enfin, si vous «perdez» votre vue de défilement dans le générateur d’interface (il est possible de la fermer pour qu’elle disparaisse de la grille de conception), ne paniquez pas. il suffit de cliquer dessus dans la liste d'objets à gauche de la grille de création.

4
unsynchronized

Bon nombre des réponses ci-dessus sont trompeuses ou obsolètes. À compter de 2017 (peut-être beaucoup plus tôt), le constructeur d'interface ne prend-il en charge les vues de défilement avec un contenu automatiquement dimensionné. L'astuce est que XCode donne une signification particulière et non standard aux contraintes entre le scrollview et le contenu qu'il contient. Ces contraintes "internes" auront pas une incidence sur la taille du contenu, comme vous pouvez vous attendre autrement. 

Cela signifie que vous pouvez par exemple faites que votre vue de défilement soit épinglée au bas de la vue principale avec une marge zéro et que son contenu soit épinglé au bas de la vue à une marge zéro, mais le contenu ne sera pas étiré de cette manière. Au lieu de cela, le contenu obtiendra sa taille déterminée par lui-même (voir ci-dessous), ainsi que la taille de la zone de défilement dans l'affichage de défilement.

Pensez-y comme ceci - Il existe une asymétrie dans les contraintes de liaison à une vue de défilement: les contraintes de la vue de défilement au monde "extérieur" (parent) déterminent la taille et la position de la vue de défilement comme d'habitude. Mais les contraintes "à l'intérieur" de la vue de défilement déterminent réellement la taille et la position de la zone de défilement de la vue de défilement, en la liant au contenu.

Ceci est totalement non évident car, lorsque vous allez définir les contraintes, XCode suggérera toujours l'espacement actuel et il ne vous arrivera jamais de changer intentionnellement les contraintes entrantes et sortantes de manière à créer des conflits. Mais vous pouvez et ils ont la signification décrite ci-dessus: on contrôle la disposition scrollview et on contrôle la taille de la zone de contenu défilable.

Je suis tombé par hasard sur cela et ensuite, voyant comment cela semblait fonctionner, cela me conduit à cet article qui l'explique complètement et cite la source de la documentation Apple pour ceci:

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

Un dernier élément d’information essentiel, à propos de la taille autodéterminée du contenu: vous pouvez avoir l’impression que vous êtes dans une impasse parce que vous adaptez normalement votre contenu à, par exemple. la largeur de la vue parent, mais dans ce cas, le parent est le scrollview et comme décrit ci-dessus - la contrainte n'affectera pas la taille de votre contenu. La solution ici est de vous rappeler que vous pouvez limiter les éléments aux éléments qui ne sont pas directement voisins dans votre hiérarchie de vues: par exemple. Vous pouvez définir la largeur de votre vue de contenu sur la largeur de la vue principale au lieu d’essayer en vain d’obtenir le défilement pour le faire à votre place.

4
Pat Niemeyer

Dans Xcode 4.5, avec Autolayout, je n’ai pas de section «Inserts de contenu» dans mon inspecteur de taille. J'ai donc dû l'ajouter sous Attributs d'exécution définis par l'utilisateur, puis cela a bien fonctionné. 

Ce que vous ajoutez dans "Attributs d'exécution définis par l'utilisateur" est keyPath == contentInset de type "Rect" (UIEdgeInsets, qui a la même entrée qu'un Rect) et est défini comme {haut, gauche}, {bas, droite}. ContentSize ne définit que la région de la fenêtre à défilement. contentInset définit la zone de défilement. 

J'espère que cela aide quelqu'un dans la même situation. 

4
Robert Wasmann

Supprimez simplement l'autoLayout sur votre scrollview. alors le code est aussi simple que cela:

scrollviewName.contentSize = CGSizeMake(0, 650);

il suffit de créer une propriété iboulet sur un fichier .h, puis de la synthétiser sur un fichier .m. Assurez-vous que le défilement est activé.

2
Aldrin Equila

La configuration d'un UIScrollView via Interface Builder n'est pas intuitive. Voici ma liste de contrôle pour la mise en place:

  1. Sélectionnez le fichier XIB UIViewController. Dans "Inspecteur d'identité" du constructeur d'interface, remplacez UIView par le type de classe UIScrollView. 

  2. Sous "Inspecteur de fichier", décochez la case Autolayout

  3. Sous "Inspecteur d'attributs", changez la taille en forme libre. Vous pouvez ensuite étirer manuellement la vue de défilement ou spécifier une largeur et une hauteur personnalisées sous "Inspecteur de taille".

  4. Dans "Inspecteur d'identité", ajoutez un nouvel attribut d'exécution défini par l'utilisateur, appelé "contentSize" de type "Taille", puis remplacez-le par une valeur telle que {320, 1000}. Vous ne pouvez plus définir cela par programme et vous devez donc cette étape pour que la vue Défilement sache que le contenu de la vue Défilement est plus grand que la fenêtre. 

2
Free Mason

Si vous cliquez sur l'icône Propriétés de n'importe quel contrôleur de vue dans Interface Builder, vous pouvez le définir sur une taille "de forme libre" dans les métriques simulées et modifier la taille de la vue principale afin qu'elle corresponde à la taille de contenu souhaitée.

De cette façon, vous pouvez créer le contenu de votre ScrollView comme s'il s'agissait d'une seule vue agrandie. Comme il ne s’agit que d’une mesure simulée, votre contrôleur View sera redimensionné par rapport aux limites de la fenêtre lorsqu’elle sera chargée.

2
oliland

Vous pouvez avoir UIScrollView dans StoryBoard avec des autolayouts . En gros, il vous faut:

  1. Ajouter UIScrollView 
  2. Ajoutez-y toutes les contraintes (comme les encarts des bords supérieur, gauche, droit et inférieur) 
  3. Ajouter un 'conteneur' UIView à UIScrollView 
  4. Si vous souhaitez simplement faire défiler dans un sens (par exemple, vertical): Définir la hauteur explicitement (pour l'instance, 600) et lier la largeur à la largeur de UIScrollView. 
  5. Si vous souhaitez un défilement bidirectionnel, définissez simplement la largeur et la hauteur. 

storyboard setup

1
Eugene Braginets

Oui, st3fan a raison, la propriété contentSize de UIScrollView doit être définie sur . Cependant, vous ne devez pas désactiver la mise en pause automatique à cette fin. Vous pouvez facilement configurer contentSize d’UIScrollView avec autolayout dans IB uniquement, sans code.

Il est important de comprendre que lorsque vous utilisez autolayout contentSize of UIScrollView n'est pas défini directement, il est calculé en fonction des contraintes de toutes les sous-vues de UIScrollView. Et tout ce dont vous avez besoin est de fournir les contraintes appropriées pour les sous-vues dans les deux sens. 

Par exemple. si vous ne possédez qu'une seule sous-vue, vous pouvez définir sa hauteur et son espace de haut en bas sur superview (c'est-à-dire scrollView dans notre cas) contentSize.height est calculé en tant que somme

Vertical Space (aSubview.top to Superview.top) + aSubview.height + Vertical Space (aSubview.top to Superview.top)

contentSize.width est calculé de manière similaire à partir de contraintes horizontales.

S'il y a trop peu de contraintes pour calculer contentSize correctement, un petit bouton rouge s'affiche près de l'élément View Controller Scene pour informer de l'ambiguïté de la présentation. 

S'il y a beaucoup de sous-vues, il peut s'agir d'une "chaîne" de contraintes: sous-vue de haut en haut, hauteurs et espaces entre les sous-vues et sous-vue de dessous, comme dans Danyal Aytekin answer.

Mais dans la plupart des cas, il est plus pratique d'ajouter une vue vide avec la taille requise et de définir des espaces en haut, gauche, en bas et à droite de scrollView sur 0. Vous pouvez utiliser cette vue comme "contenu "Afficher", c’est-à-dire y placer toutes les autres sous-vues ou si vous avez déjà plusieurs sous-vues et que vous ne voulez pas les déplacer ni les réorganiser, vous pouvez ajouter cette vue auxiliaire aux sous-vues existantes et la masquer.

Pour que scrollView puisse faire défiler le contenu calculé, la taille du fichier doit être supérieure à celle de scrollView. 

1
Vladimir

Voici une solution pour concevoir ScrollView avec un contenu plus grand que l'écran entièrement dans Storyboard (enfin, presque entièrement, vous devrez également ajouter une seule ligne de code).

https://stackoverflow.com/a/19476991/1869369

0
Ronny Webers

Je trouve un moyen plus pratique.

1: Échelle la taille de la vue de défilement pour contenir toute l'interface utilisateur à l'intérieur.

2: Ajouter un iboutlet de la vue par défilement.

3: Dans viewDidLoad, enregistrez le frame.size de la vue de défilement.
(par exemple, _scrollSize = _scrollView.frame.size;)

4: Dans viewWillAppear, définissez contentSize par la taille CGS que vous avez précédemment enregistrée.
(par exemple, _scrollView.contentSize = _scrollSize;)

5: Fait ~

0
Agas
  1. Ajouter UIViewController
  2. Dans UIViewController 'Attribute Inspector -> Taille de la métrique simulée' 
  3. Dans UIViewController 'Size Inspector -> View Controller', hauteur définie 800
  4. Ajouter UIScrollView dans UIViewController
  5. Ajouter toutes les contraintes à UIScrollView (haut, gauche, droite, bas) et ajouter l'alignement X = centre
  6. Ajouter UIView dans UIScrollView
  7. Ajoutez toutes les contraintes à UIView (haut, gauche, droite, bas) et ajoutez l’alignement X = centre. Oui, comme pour UIScrollView dans # 3, mais pour UIView
  8. Ajouter une contrainte de hauteur à UIView. Par exemple 780
  9. Courir

 Storyboard

0
Alexander

Créer un nouveau projet Xcode

Accédez au fichier Main.storyboard

Sélectionnez ScrollView dans la bibliothèque d'objets.

Définir le cadre pour le ScrollView.

Ajoutez une autre vue pour faire défiler la vue et conservez le cadre identique à celui de ScrollView.

Maintenant, vous pouvez définir dynamiquement sa hauteur et sa largeur. Configurer UIScrollView à l'aide de la disposition automatique sous XIB

0
user2613580