web-dev-qa-db-fra.com

Comment utiliser Autolayout pour définir des contraintes sur mon UIScrollview?

J'ai passé deux jours à essayer différentes solutions pour approches Mixte et Pure Autolayout pour réaliser ce qui était une configuration de scrollview triviale avant l'autolayout, et c'est maintenant officiel - je dois être trop stupide. Je l’installe principalement dans Storyboard (enfin, c’est comme ça).

Alors, voici mon appel à l'aide.

Viewtree:

UIView
-UIView
-UIView
..-UIScrollview
...-UIButton
...-UIButton
...-UIButton

Les boutons sont supposés défiler horizontalement (de gauche à droite et inversement). Quelqu'un peut-il s'il vous plaît me faire savoir comment définir les contraintes pour y parvenir en utilisant Autolayout pur ???

-

J'ai essayé l'approche mixte, comme ceci:

UIView
- UIView
- UIView
..-UIScrollview
...-UIView (contentview)
....-UIButton
....-UIButton
....-UIButton

... et en définissant des contraintes de largeur et de hauteur fixes pour les paramètres contentview et translatesAutoresizingMaskIntoConstraints conformément à la note technique d'Apple. Les boutons et la vue de défilement sont configurés à l'aide de contraintes. Cela fait défiler la vue de défilement (yay) mais hélas, ça défile trop! Autant que je sache, la largeur de défilement est en quelque sorte doublée par rapport à ce que je règle la contentview à ??? !!! ???

J'ai aussi essayé la méthode de l'autolayout pur, à la fois avec contentview et sans. Toutes les vues sont translatesAutoresizingMaskIntoConstraints=NO, sauf pour self.view. Les boutons ont des contraintes de largeur/hauteur fixes et sont épinglés aux quatre bords de la vue à défilement. Rien ne défile.

Je ne comprends donc pas pourquoi je ne parviens pas à le faire fonctionner correctement. Toute aide est très appréciée, et si vous avez besoin d’autres informations, n'hésitez pas à demander!

MISE À JOUR Copie d'écran avec la solution - contraintes de buttonZ:

enter image description here

EDIT @ Jamie Forrest La solution s'avère donc être une contrainte de fin erronée pour le dernier bouton. Au lieu de 6441, la valeur que j'avais définie était négative, -6441. Le problème, c’est que lors de la définition de la valeur dans le storyboard, la barre d’outils Épingler offre deux options:

enter image description here

La valeur actuelle du canevas est négative (il n’ya pas de défilement) et l’option ci-dessous est positive (activation du défilement). Cela signifie que je ne suis pas stupide mais au moins à moitié aveugle je suppose. Bien que, pour ma défense, ne soit-il pas quelque peu gênant que XCode n'indique pas d'erreur pour le réglage "incorrect"?

EDITE ENCORE Maintenant, c'est amusant ... changer la valeur de fin de -6441 (pas de défilement) à 6441 activé. Mais mon vieil ami, le "trop ​​grand contenu" était de retour, ce qui a conduit à une taille de contenu deux fois plus grande que ce qu'elle devrait être! La solution pour obtenir le défilement correct du contenu consistait à définir la contrainte de fin sur ZERO! Cela n’est pas évident lorsque vous travaillez dans Storyboard, mais que vous regardez le code de @Infinity James, c’est ce qu’il devrait être.

173
user1459524

Il est difficile de voir les valeurs exactes et la configuration de vos contraintes lorsque vous les avez collées ici. Je ne suis donc pas sûr de regarder sur vos captures d'écran où vous vous êtes trompé.

Au lieu d'expliquer ce qui ne va pas dans votre configuration, j'ai créé un exemple de projet avec une hiérarchie de vues et une configuration de contraintes très similaires à celles que vous décrivez. Le défilement horizontal fonctionne comme prévu dans l'exemple de projet, qui utilise l'approche "Pure AutoLayout" décrite par Apple dans la note technique .

J'ai également eu beaucoup de mal à faire fonctionner Auto Layout avec UIScrollView à l'origine. La clé pour le faire fonctionner est de s’assurer que tous les éléments de la vue défilement, pris ensemble, ont des contraintes qui lient finalement à tous les côtés de la vue défilement et qui permettent au système AutoLayout de déterminer un contentSize pour le faire défiler la vue qui sera plus grande que son cadre. Il semble que vous essayiez de faire cela dans votre code, mais vous aviez peut-être des contraintes superflues qui rendaient la taille de contentSize trop petite.

Il convient également de noter que, comme d'autres l'ont mentionné, avec AutoLayout et UIScrollview, vous ne définissez plus explicitement contentSize. Le système AutoLayout calcule le contentSize en fonction de vos contraintes.

J'ai aussi trouvé ce chapitre de l'ebook très utile pour me faire comprendre comment tout cela fonctionne. J'espère que tout ça aide.

65
Jamie Forrest

LOL bienvenue au club de la stupidité. Je suis l'un des fondateurs. :RÉ

Pour le défilement VERTICAL : le seul moyen de le faire fonctionner (iOS 8, Xcode 6 et autolayout pur) consistait à ajouter les contraintes suivantes à ma vue Défilement. (tous liés à la superview):

  • Égales Largeurs
  • Des hauteurs égales
  • Alignement centre Y
  • Alignement du centre X

Ma structure:

  UIView
   - ScrollView
    - Subview
    - Subview
    - Subview
    - Subview
    - ...

C'est le résultat final:

Demo

C'est la configuration:

Setup plein écran

Et voici le projet .

Espérons que cela éviterait à quelqu'un d'aller à dormir AT 5 heures du matin. :RÉ

48
backslash-f

Exemple simple et autonome

À en juger par le nombre élevé de votes sur la question et le faible nombre de votes sur les réponses, les gens ne trouvent pas de solution compréhensible et rapide ici. Laissez-moi essayer d'en ajouter un. Ce projet est un exemple autonome entièrement réalisé dans Interface Builder. Vous devriez être capable de le faire en 10 minutes ou moins. Ensuite, vous pouvez appliquer les concepts que vous avez appris à votre propre projet.

enter image description here

La question initiale concerne les boutons de défilement. Ici, je viens d'utiliser UIViews mais ils peuvent représenter la vue de votre choix. J'ai également choisi le défilement horizontal car les captures d'écran du storyboard sont plus compactes pour ce format. Les principes sont les mêmes pour le défilement vertical, cependant.

Concepts clés

  • La UIScrollView ne devrait utiliser qu'une seule sous-vue. Il s'agit d'un 'UIView' qui sert d'affichage de contenu pour tout ce que vous souhaitez faire défiler.
  • Faites en sorte que la vue du contenu et celle du défilement parent ​​aient les mêmes hauteurs que le défilement horizontal. (Largeur égale pour le défilement vertical)
  • Assurez-vous que tout le contenu défilant a une largeur définie et est épinglé de tous les côtés.

Commencer un nouveau projet

Il peut s'agir simplement d'une application à vue unique.

Storyboard

Dans cet exemple, nous allons faire une vue de défilement horizontal. Sélectionnez le contrôleur de vue, puis choisissez forme libre dans l'inspecteur de taille. Faites la largeur 1,000 et la hauteur 300. Cela nous donne juste la place sur le storyboard pour ajouter du contenu qui défilera.

enter image description here

Ajouter une vue de défilement

Ajoutez un UIScrollView et épinglez les quatre côtés à la vue racine du contrôleur de vue.

enter image description here

Ajouter une vue de contenu

Ajoutez une UIView en tant que sous-vue à la vue de défilement. Ceci est la clé. N'essayez pas d'ajouter beaucoup de sous-vues à la vue de défilement. Il suffit d'ajouter un seul UIView. Ce sera votre vue de contenu pour les autres vues que vous voulez faire défiler. Épinglez la vue du contenu à la vue de défilement sur les quatre côtés.

enter image description here

Égalité de hauteur

Maintenant dans la structure du document, Command Cliquez à la fois sur la vue Contenu et sur la vue défilante vue parent ​​pour les sélectionner tous les deux. Puis définissez les hauteurs pour être égal (Control glisser de la vue du contenu vers la vue du défilement). Ceci est également essentiel. Étant donné que nous faisons défiler horizontalement, la vue du contenu de la vue de défilement ne saura pas à quelle hauteur elle devrait être si nous ne la définissons pas de cette façon.

enter image description here

Remarque:

  • Si nous faisions défiler le contenu verticalement, nous définirions la largeur de la vue de contenu sur la largeur du parent de la vue de défilement.

Ajouter du contenu

Ajoutez trois UIViews et donnez-leur toutes les contraintes. J'ai utilisé 8 marges de points pour tout.

enter image description here

Contraintes:

  • Vue verte: épinglez les bords supérieur, gauche et inférieur. Faire la largeur 400.
  • Vue rouge: épinglez les bords supérieur, gauche et inférieur. Faire la largeur 300.
  • Vue violette: épinglez les quatre bords. Faites la largeur quel que soit l'espace restant (268 dans ce cas).

Le ​​réglage des contraintes de largeur est également essentiel afin que la vue de défilement sache à quel point sa vue de contenu sera étendue.

Fini

C'est tout. Vous pouvez exécuter votre projet maintenant. Il devrait se comporter comme l'image défilante en haut de cette réponse.

Pour le défilement vertical, intervertissez simplement les directions de largeur et de hauteur dans cet exemple (testé et fonctionnel).

Une étude plus approfondie

30
Suragch

ContentSize est défini implicitement en appliquant les contraintes à l'intérieur de UIScrollView.

Par exemple, si vous avez un UIScrollView à l'intérieur d'un UIView, il ressemblera à ceci (comme vous le savez sûrement):

    UIView *containerView               = [[UIView alloc] init];
    UIScrollView *scrollView            = [[UIScrollView alloc] init];
    [containerView addSubview:scrollView];
    containerView.translatesAutoresizingMaskIntoConstraints = NO;
    scrollView.translatesAutoresizingMaskIntoConstraints    = NO;
    NSDictionary *viewsDictionary       = NSDictionaryOfVariableBindings(containerView, scrollView);

    [containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollView]|"
                                                                          options:kNilOptions
                                                                          metrics:nil
                                                                            views:viewsDictionary]];
    [containerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView]|"
                                                                          options:kNilOptions
                                                                          metrics:nil

Cela définira le scrollView pour qu'il remplisse la taille du conteneurView (le conteneurView devra donc avoir une certaine taille).

Vous pouvez ensuite ajuster le contentSize de UIScrollView en le définissant implicitement pour qu'il soit assez grand pour contenir les boutons comme ceci:

    UIButton *buttonA                   = [[UIButton alloc] init];
    UIButton *buttonB                   = [[UIButton alloc] init];
    UIButton *buttonC                   = [[UIButton alloc] init];
    [scrollView addSubview:buttonA];
    [scrollView addSubview:buttonB];
    [scrollView addSubview:buttonC];
    buttonA.translatesAutoresizingMaskIntoConstraints       = NO;
    buttonB.translatesAutoresizingMaskIntoConstraints       = NO;
    buttonC.translatesAutoresizingMaskIntoConstraints       = NO;

    viewsDictionary                     = NSDictionaryOfVariableBindings(scrollView, buttonA, buttonB, buttonC);

    [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[buttonA]-|"
                                                                       options:kNilOptions
                                                                       metrics:nil
                                                                         views:viewsDictionary]];
    [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[buttonA]-[buttonB]-[buttonC]-|"
                                                                       options:NSLayoutFormatAlignAllBaseline
                                                                       metrics:nil
                                                                         views:viewsDictionary]];
9
Infinity James

Il y a tellement de questions sur l'utilisation de AutoLayout avec UIScrollView, le point clé que nous ignorons est que les vues internes de UIScrollView imposent des contraintes à la vue Contenu mais pas le UIScrollView lui-même. Reportez-vous à la Note technique TN2154 , vous trouverez:

La classe UIScrollView fait défiler son contenu en modifiant l'origine de ses limites. Pour que cela fonctionne avec la disposition automatique, les bords supérieur, gauche, droit et à l'intérieur d'une vue de défilement désignent maintenant les bords de sa vue de contenu.

La figure suivante montre que: enter image description here

Vous pouvez trouver que l'espace de fin est de 500 points. Si la contrainte est appliquée à UIScrollView, la vue sera manquante et devra être mise à jour de son cadre. Cependant, aucun avertissement et aucune erreur. Parce que toutes les contraintes sont contre la vue du contenu.

UIScrollView calculera la taille de la vue de contenu en fonction des contraintes des vues internes. (Pour l'exemple, la taille du contenu: width = 100 (espace de début) + 200 (largeur de la vue) + 500 (espace de fin), height = 131 (espacement supérieur) + 200 (hauteur) + 269 (espacement inférieur)

Comment ajouter des contraintes pour les vues dans UIScrollView:

  1. Imagerie des positions des vues dans la vue de contenu.
  2. Ajoutez un espacement haut, droit, bas et gauche aux bords de la vue de contenu, ainsi que la largeur et la hauteur de ces vues.

Et tout ça c'est fait.

Un moyen facile de gérer la mise en forme automatique avec scrollview consiste à ajouter une vue de conteneur contenant toutes les sous-vues dans la vue de défilement.

Conclusion: le point clé pour comprendre la mise en forme automatique avec UIScrollView est que les vues internes imposent des contraintes à la vue de contenu, mais pas à UIScrollView lui-même.

attaché exemple de code

8
Danyun Liu

La solution suivante a fonctionné pour moi pour scrollView avec autolayout et sans contentSize:

  1. Glissez n déposez un scrollView sur viewController et appliquez toutes les contraintes pour couvrir l’espace souhaité.
  2. Faites glisser n déposez un IView à l'intérieur de scrollView et faites-le couvrir tout l'espace de scrollView et appliquez-le les contraintes doivent être en haut, à gauche, à droite, en bas à partir de scrollView.
  3. Définissez la hauteur (et la largeur si le défilement horizontal est requis) de la vue interne en fonction du besoin de défilement. Cette partie peut également être réalisée à partir de code si nécessaire.
  4. Critique . Après avoir défini une hauteur importante au point (3), revenez au point (2) et assurez-vous de définir les valeurs supérieure, gauche, droite et inférieure retour à zéro comme peut l'être Xcode les a modifiées pour vous lorsque vous avez forcé la hauteur modifiée en (3).

Et tu as fini. Maintenant, vous pouvez ajouter un nombre quelconque de contrôles sur cette vue et appliquer les contraintes pertinentes les unes aux autres (qui ne semblent pas fonctionner sans cette vue). Si vous ne souhaitez pas utiliser cette vue, vous devrez appliquer des contraintes pour chaque contrôle lié à scrollView (non liées entre elles).


Le conseil irrésistible ..............

Critique. Disons que, pour plus de clarté, UIScrollView est largeur de 10 et 100 de hauteur. (En fait, normalement, ces valeurs sont dynamiques, bien sûr, en fonction de la largeur de l'appareil, etc. Mais pour l'instant, disons simplement 1000 larges et 100 hauts.) Disons que vous faites un défilement horizontal. Mettez donc UIView dans UIScrollView. (C’est la "vue du contenu".) Définissez les quatre contraintes de la vue du contenu en haut, en bas, en tête, en fin, sur la vue de défilement. Mettez-les tous à zéro même si cela semble faux. Réglez la hauteur du contenu UIView sur 100 et oubliez cela. Maintenant: vous voulez faire défiler horizontalement, définissez donc la largeur de la vue du contenu sur 1225.

Notez que la largeur de la vue de contenu est maintenant 225 fois supérieure à la largeur de la vue de défilement parent. Ce n'est pas grave: en fait, vous DEVEZ le faire. Notez que

... vous ne PAS définissez la largeur de fuite sur négative 225 ...

vous pensez que vous devez "faire correspondre" les largeurs comme vous le feriez normalement. Mais si vous faites cela, cela ne fonctionnera pas du tout.

Vous devez définir les nombres de début et de fin sur ZÉRO, jamais négatif (même si la largeur est "plus grande")

Il est intéressant de noter que vous pouvez réellement définir les nombres de début/fin sur n’importe quelle valeur positive (essayez de dire "50") et cela vous donne une sorte de marge de rebond. (Cela a souvent l’air génial: essayez-le.) Toute valeur négative à l’une ou l’autre des extrémités sera "brisée en silence".

Notez que, souvent, très Xcode (à partir de la version 7.3.1),

va "utilement" définir ces valeurs pour vous à des nombres négatifs!

car il essaie de les compter automatiquement pour vous. Si c'est le cas, il va se casser silencieusement. Définissez les quatre valeurs à zéro dans la première instance. Et définissez la largeur de la vue du contenu beaucoup plus large que le "1000" dans l'exemple.


Edited: J'ai fini par utiliser UITableView au lieu de UIScrollView pour la plupart de mes besoins. Comme tableView me semble beaucoup plus flexible et dynamique.

5
zeeawan

Je suppose que vous rencontrez des problèmes avec thecontentSize. Découvrez this blog post sur la façon de gérer la contentSize lorsqu’on utilise une approche "pure" AutoLayout. En résumé, vos contraintes définissent implicitement la taille du contenu. Vous ne le définissez JAMAIS explicitement lorsque vous utilisez AutoLayout. J'ai joint un exemple de projet à la fin de l'article pour en montrer le fonctionnement

4
Edward Huynh

Vous devriez organiser votre mise en page comme ceci
ViewControllerView contient ScrollView, ScrollView contient ContainerView, ContainerView contient 2 Labels
enter image description here

Puis suivez les 3 étapes pour que votre ScrollView puisse défiler

  1. Positionner la broche ScrollView (haut/droite/bas/gauche) sur ViewControllerView
    • Positionner la broche ContainerView (haut/droite/bas/gauche) sur ScrollView
    • Définissez Horizontally in Container (( n'est pas définissez Vertically in Container)
    • Label1 pin ( haut /droite/gauche) sur ContainerView
    • Label1 pin (droite/gauche/ bas ) à ContainerView et haut à Label1

enter image description here

ICI est le projet de démonstration

J'espère que cette aide

3
Phan Van Linh

Vous avez peut-être examiné une partie des notes techniques. Vous pouvez définir implicitement la taille du contenu d'une vue de défilement à l'aide de contraintes fixées aux bords de la vue de défilement.

Voici un exemple simple. Créez un scénarimage avec une vue, une vue par défilement. Définissez les contraintes de défilement de la vue pour l’adapter à la taille de la vue dans laquelle vous la placez.

Dans cette vue de défilement, ajoutez une vue unique. Définissez explicitement la taille de cette vue à l'aide de contraintes (et assurez-vous qu'elle est plus grande que la vue avec défilement).

Ajoutez maintenant quatre contraintes supplémentaires à cette vue interne, ce qui verrouille les quatre bords de la vue interne à la vue de défilement parent. Ces quatre contraintes entraîneront une augmentation de la taille du contenu afin de l'adapter à la vue interne.

Si vous souhaitez ajouter plusieurs vues à une vue de défilement, par exemple horizontalement, verrouillez le côté gauche de la première sous-vue à gauche de la vue de défilement, verrouillez les sous-vues horizontalement, et la droite côté de la dernière vue secondaire à droite de la vue de défilement. Ces contraintes forceraient la taille du contenu de la vue de défilement à se développer pour prendre en compte toutes les sous-vues et leurs contraintes.

3
Travis

Si votre question est "Comment puis-je mettre un groupe de UITextFields dans un UIScrollView à défilement vertical, de sorte qu'ils s'éloignent du clavier lorsqu'ils ont le focus", la meilleure réponse est:

Ne pas.

Utilisez plutôt un UITableViewController avec des cellules statiques.

Vous bénéficiez gratuitement de ce comportement de défilement et de tous les encarts de contenu Just Work si votre contrôleur de vue est affiché à l'intérieur d'un UINavigationController.

3
Robert Atkins

Problème similaire que j'ai aujourd'hui avec iOS 8.4, Xcode 6.4

Il existe une vue contenant une vue de défilement, contenant un contentView (UIView) contenant des sous-vues.

Tout est mise en page automatique partout. Les bords de la vue de défilement sont épinglés aux bords de la vue parent avec des contraintes. Les bords de la vue de contenu sont épinglés aux bords de la vue de défilement avec des contraintes.

À l'origine, la vue du contenu refusait de dimensionner sur toute la largeur de la vue de défilement. J'ai dû ajouter une contrainte supplémentaire sur la vue de contenu pour que sa largeur corresponde à la vue de défilement parent. Ou je pourrais définir une contrainte contentView.centerX == scrollView.centerX. En plus de cerner les contours, l’un ou l’autre de ceux-ci a soudainement modifié la taille du contenu.

// Either one of these additional constraints are required to get autolayout to correctly layout the contentView. Otherwise contentView size is its minimum required size
scrollView.addConstraint(NSLayoutConstraint(item: contentView, attribute: .CenterX, relatedBy: .Equal, toItem: scrollView, attribute: .CenterX, multiplier: 1.0, constant: 0))
scrollView.addConstraint(NSLayoutConstraint(item: contentView, attribute: NSLayoutAttribute.Width, relatedBy: .Equal, toItem: scrollView, attribute: .Width, multiplier: 1.0, constant: 0.0))

Épingler les bords de la vue de contenu à la vue de défilement en utilisant des contraintes visuelles du formulaire,

let cvConstraints = ["H:|[contentView]|", "V:|[contentView]|"]

J'utilise une routine pour parcourir le tableau et les ajouter au scrollView.

1
David

J'ai fait face à un problème similaire. Je définissais chaque contrainte et je me demandais toujours pourquoi elle redimensionnait toujours certaines sous-vues. Ma solution a été de définir clipsToBounds sur YES.

1
i89

L’approche autolayout pure fonctionne à merveille, mais il est très difficile d’être configuré si vous migrez de non autolayout. Je l'ai déjà fait plusieurs fois et j'ai quelques conseils d'ordre général:

  • Commencez petit: même si cela implique de recréer vos vues de storyboard, commencez avec quelques éléments et construisez-les lentement, en vous assurant de vérifier que le défilement fonctionne après avoir ajouté quelques éléments.
  • Désactivez translatesAutoresizingMaskIntoConstraints sur tout: cela a toujours été la cause des conflits de contraintes pour moi.
  • Définissez correctement vos contraintes UIScrollView: assurez-vous que la vue de défilement est connectée de tous les côtés à la vue parent, sinon elle ne sera tout simplement pas étendue.
1
Nick

Si, comme moi, vous utilisez simplement du contenu statique sans contraintes dans la sous-vue, vous pouvez le faire comme ceci:

override func viewDidLayoutSubviews() {
    scrollView.contentSize = CGSizeMake(320, 800)
}
1
Antzi

J'ai passé des jours à essayer de trouver une solution à l'utilisation de l'affichage automatique de défilement dans l'affichage automatique, afin de centrer la vue de défilement sur l'écran visible, qui fonctionne pour tous les périphériques/dimensions de l'écran, ainsi que pour la rotation de l'écran.

J'ai passé des jours à essayer de le faire avec Autolayout uniquement, et je me suis approché mais jamais assez près. Donc, au final, j'ai dû ajouter 3 lignes de code par écran, dans viewDidLoad.

Voir la solution ci-dessous:

  1. Créez la vue de défilement et remplissez-la avec les objets de votre choix
  2. Activer la mise en page automatique
  3. Puis centrez le ScrollView verticalement et horizontalement Centre ScrollView
  4. Sélectionnez le View et ensuite 'Ajouter les contraintes manquantes' - cela fait son effet
  5. Le résultat est que beaucoup de contraintes sont générées. Deux nouvelles vues ont été créées pour la vue: 'Horiz space scrollview to View' et 'Vert space scrollview to view' ou vice-versa.
  6. Supprimez la 'vue de défilement Horiz de l'espace vers la vue' pour laisser 3 contraintes sur la vue. Le 2 pour entrer la vue de défilement dans la vue et celui pour définir un espace vertical entre la vue de défilement et la vue
  7. Liez maintenant la contrainte Vert à votre code en cliquant dessus et en maintenant la touche Ctrl enfoncée, en la faisant glisser dans le fichier d'en-tête et en créant un IBOutlet NSLayoutConstraint (j'ai appelé mine constraintVertVtoSV).
  8. Maintenant, allez dans le fichier .m et ajoutez ces lignes de code dans viewDidLoad (jouez avec le montant de remplissage pour obtenir le centrage vertical correct)

    if (IPAD)
    

    {self.constraintVertVtoSV.constant = 150.0; }

  9. cela devrait maintenant fonctionner sur tous les appareils et être correctement centré et toujours bien défiler.

1
Guy

Au bout d’un certain temps, j’ai finalement trouvé une solution. Je travaille avec des storyboards de classes universelles (600x600). J'ai créé un UIView (contentView) de la taille du scrollView et créé des contraintes pour le haut, le bas, le début et la fin du scrollView. Ensuite, j'ai découpé manuellement la taille de contentView à 600x600. Le storyboard a cessé d'essayer de tout redimensionner et je pouvais travailler, mais la vue était horrible sur le vrai appareil ou le simulateur. J'ai fait 2 sorties de contrainte de cette taille écrêtée.

@property (weak, nonatomic) IBOutlet NSLayoutConstraint *contentViewWidthConstraint; 
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *contentViewHeightConstraint;

Puis dans viewDidLoad

CGSize viewSize = self.view.frame.size;
self.contentViewWidthConstraint.constant = viewSize.width;
self.contentViewHeightConstraint.constant = viewSize.height;

Fonctionne très bien.

1
Cristian Pena

Dans Swift, vous pouvez utiliser cette solution de travail.

Contraints

ScrollView: Début, Fin, Haut, Bas = Superview

ContentView: Début, Fin, Haut, Bas = ScrollView. Hauteur fixe/par rapport au contenu.

Vous pouvez définir la contrainte de largeur (contentView) sur égale à scrollviews superview, mais sélectionnez remove remove au moment de la création, car vous allez ajouter cette contrainte par programmation. C'est juste pour que l'IB ne se plaint pas d'avertissements.

extension UIView {

    func setupContentViewForViewWithScroll(contentView vwContent : UIView) {
        //Set constraint for scrollview content
        let constraint = NSLayoutConstraint(item: vwContent, attribute: NSLayoutAttribute.Width, relatedBy: .Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: self.bounds.size.width)
        vwContent.addConstraint(constraint)
        self.layoutSubviews()
    }

}

Et dans le contrôleur de vue viewDidLayoutSubviews je viens d'appeler cette méthode:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    self.view.setupContentViewForViewWithScroll(contentView: vwContent)
}
1
Ibrahim Yildirim

Je sais que c'est une solution simple pour un profane et non pas ce que Apple suggère dans le document, mais cela a fonctionné deux fois pour moi, avec un contenu différent et peut être configuré très rapidement: Dans le contrôleur de vue de scénario, insérez UIView. Dans UIView, insérez une vue de tableau, dynamique, 0 cellules de prototype, style brut ou groupé. En mode Table, insérez une vue de défilement. En mode de défilement, insérez du contenu. C'est ça, pas de paramètres dans le contrôleur de vue personnalisé.

0
Rinaldo