175 votes

Officiellement, je suis trop stupide pour UIScrollview avec mise en forme automatique

J'ai passé deux jours à essayer les différentes solutions Mixtes et Pures mise en page automatique des approches pour parvenir à ce qui a été une mince scrollview de l'installation avant la mise en forme automatique, et c'est maintenant officiel: je dois être trop bête. Je suis cette mise en place principalement dans le Storyboard (bon, c'est juste la façon dont il est).

Voici donc mon appel à l'aide.

Viewtree:

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

Les boutons sont censés pour faire défiler horizontalement (de gauche à droite et vice-versa). Quelqu'un peut-il svp laissez-moi savoir comment définir les contraintes pour réaliser cela à l'aide de pure mise en forme automatique???

--

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

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

...et paramètre fixe la largeur et la hauteur des contraintes pour l' contentview et de la translatesAutoresizingMaskIntoConstraints paramètres comme par Apple note technique. Les boutons et le scrollview sont mis en place à l'aide de contraintes. Cela devient la scrollview de défilement (yay), mais hélas, ça défile trop loin! Aussi loin que je peux dire, le défilement largeur est en quelque sorte doublé de ce que j'ai mis le contentview???!!!???

J'ai essayé de la pure mise en forme automatique approche, à la fois avec contentview et sans. Tous les points de vue sont - translatesAutoresizingMaskIntoConstraints=NO, sauf pour l' self.view. Les boutons ont une largeur fixe/contraintes de hauteur, et sont épinglés à tous les quatre bords de la scrollview. Rien de parchemins.

Donc, je suis totalement perplexe pourquoi je ne peux pas le faire fonctionner correctement. Toute aide est très appréciée, et si vous avez besoin d'autres infos, merci de demander!

EDIT @l'Infini James J'ai recréé votre code exactement dans le storyboard, mais il n'est pas de défilement. (La scrollview contentsize.la largeur est enregistré comme 279, btw). Captures d'écran:

containerview contraintes:

enter image description here

le scrollview contraintes:

enter image description here

buttonA contraintes:

enter image description here

Mise à JOUR de Capture d'écran avec la solution buttonZ contraintes:

enter image description here

EDIT @ Jamie Forrest Si la solution s'avère être le tort de fuite contrainte sur le dernier bouton. Au lieu de 6441, la valeur que j'avais mis était négatif, -6441. La chose la plus délicate est, que lors de la fixation de la valeur dans la table de montage séquentiel, il y a deux options dans le code Pin de la barre d'outils:

enter image description here

Le dessin Actuel de la Valeur est négative (ne menant à aucune de défilement), et l'option ci-dessous est positif (activation de défilement). Cela signifie que je ne suis pas stupide, mais au moins à moitié aveugle, je suppose. Bien que, pour ma défense, n'est-ce pas un peu inquiétant que XCode n'indique pas une erreur pour la "mauvaise"?

RÉÉDITÉ Maintenant, c'est drôle... en changeant le point à la valeur de -6441 (pas de défilement) 6441 permis de défilement. Mais mon vieil ami, le "trop de contentsize" était de retour, conduisant à un contenu de taille deux fois plus grande que ce qu'elle devrait être! La solution pour obtenir le contenu de défilement a été de mettre le point à la contrainte à ZÉRO! Ce n'est pas évident lorsque l'on travaille dans le Storyboard, mais en regardant @l'Infini-Jacques-de-code, c'est ce qu'il devrait être.

67voto

Jamie Forrest Points 2145

Il est difficile de voir les valeurs exactes et la configuration de vos contraintes que vous avez collé ici, donc je ne suis pas sûr de regarder vos captures d'écran où vous êtes allé mal.

Au lieu d'une explication de ce qui est mal dans votre installation, j'ai créé une base de projet de l'échantillon avec une opinion très similaire de la hiérarchie et de la contrainte de l'installation de celui que vous décrivez. Le défilement horizontal fonctionne comme prévu dans l'exemple de projet qui utilise la "Pure mise en forme automatique" approche qu'Apple décrit dans la Note Technique.

J'ai aussi eu beaucoup de problèmes à l'origine, l'obtention de Disposition Automatique de travailler avec UIScrollView. La clé pour obtenir pour fonctionner est de s'assurer que tous les éléments dans le défilement de la vue, pris ensemble, ont des contraintes que, finalement, le lien de tous les côtés de défilement de la vue et à contribuer à la mise en page automatique système soit en mesure de déterminer un contentSize pour le défilement de la vue qui sera plus grand que son cadre. On dirait que vous essayez de le faire dans votre code, mais peut-être que vous avez eu quelques superflu contraintes qui ont fait le contentSize trop petit.

A noter également, comme d'autres l'ont mentionné, avec mise en page automatique et UIScrollview, vous n'avez plus à régler la contentSize explicitement. La mise en page automatique Système calcule la contentSize basé sur vos contraintes.

J'ai aussi trouvé cet ebook chapitre très utile en me faisant comprendre comment tout cela fonctionne. Espérons que tout cela aide.

9voto

Infinity James Points 1503

Le contentSize est implicitement défini par l'application de contraintes à l'intérieur de la UIScrollView.

Par exemple, vous avez un UIScrollView à l'intérieur d'une UIView, il ressemblera à ceci (je suis sûr que vous connaissez):

    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

Qui va définir la scrollView pour remplir la taille de la containerView (donc le containerView devra être d'une certaine taille).

Vous pouvez ensuite ajuster la contentSize de la UIScrollView par implicitement un réglage à être 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]];

8voto

Danyun Points 925

Il ya tellement de nombreuses questions sur l'utilisation de la mise en page automatique avec UIScrollView, le point clé qui nous ignorent, c'est que l'intérieur des vues de la UIScrollView faire de contraintes à l'encontre de la Vue de Contenu , mais pas le UIScrollView lui-même. Reportez-vous à la Note Technique TN2154, vous pouvez trouver:

Le UIScrollView classe fait défiler son contenu en changeant l'origine de ses limites. Pour faire ce travail avec Mise en page Automatique, haut, gauche, bas, droite et les bords à l'intérieur d'un défilement de l'affichage est maintenant signifie que les bords de son contenu à afficher.

L'illustration suivante montre que: enter image description here

Vous pouvez trouver l'espace arrière est de 500 points, si la contrainte est faite à la UIScrollView, l'affichage va être miss placé et devrait être mise à jour de son cadre. Cependant, aucun avertissement et sans erreurs. Parce que toutes les contraintes sont contre l'affichage du contenu.

UIScrollView permettra de calculer la taille de l'affichage du contenu en fonction des contraintes de l'intérieur de la vue. (Pour l'exemple, le contenu taille: largeur = 100(espace) + 200 (vue de largeur) + 500 (espace arrière), hauteur = 131 (en haut de l'espacement) + 200(hauteur) + 269(espacement)

Comment ajouter des contraintes pour les vues dans le UIScrollView:

  1. L'imagerie de la position des points de vue dans la vue de contenu.
  2. Ajouter en haut, à droite, en bas, à gauche de l'espacement sur les bords de l'affichage du contenu, en outre, la largeur et la hauteur de ces points de vue.

Et tout ce qu'il fait.

Un moyen facile de traiter avec mise en page automatique avec le scrollview est d'ajouter un conteneur contenant tous les sous-vues dans le défilement de la vue.

Conclusion: le point clé pour comprendre la mise en page automatique avec UIScrollView est intérieure vue sur les contraintes à l'encontre de l'affichage du contenu, mais pas UIScrollView lui-même.

joint un exemple de code

4voto

Edward Huynh Points 1651

je suppose que vous rencontrez des problèmes avec l'contentSize. Consultez cet article de blog sur la façon dont vous gérer le contentSize lors de l'utilisation d'un "pur" approche de mise en page automatique. http://infinite-edward.tumblr.com/post/66865604683/uiscrollview-contentsize-and-autolayout-gotcha. L'essentiel, c'est que vos contraintes définissent implicitement la taille du contenu. Vous n'avez JAMAIS la définir explicitement lors de l'utilisation de mise en page automatique. J'ai attaché exemple de projet à la fin de l'article du blog pour vous montrer comment il fonctionne

3voto

Travis Points 600

Il y a un morceau dans la tech notes que vous avez peut-être regardé de plus. Vous pouvez implicitement défini la taille du contenu d'un défilement de l'affichage à l'aide de contraintes fixées sur les bords de défilement de la vue.

Voici un exemple simple. Créer un storyboard avec un point de vue, qui a un défilement de l'affichage. Jeu de défilement des vues contraintes à l'adapter à la taille de la vue que vous mettez dans.

L'intérieur que de défilement en vue d'ajouter une seule vue. Définir explicitement la taille de ce point de vue à l'aide de contraintes (et assurez-vous que la taille est plus grande que le défilement de l'affichage).

Ajoutez maintenant quatre plus de contraintes à l'intérieur verrouillage de la vue, les quatre bords du point de vue interne à son parent de défilement de la vue. Ces quatre contraintes cause de la taille du contenu de l'étendre à accueillir le point de vue interne.

Si vous avez plusieurs points de vue que vous souhaitez ajouter à un défilement de l'affichage, par exemple disposés horizontalement, vous souhaitez verrouiller le côté gauche de la première sous-vue à la gauche du défilement de l'affichage, verrouillage de la sous-vues à l'horizontale, et le côté droit de la dernière sous la vue sur le côté droit de défilement de la vue. Ces contraintes serait forcer la taille du contenu de défilement de la vue de développer pour s'adapter à tous les sous-vues et à leurs contraintes.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X