iOS mise en page automatique avec UIScrollview: Pourquoi l'affichage du contenu de défilement de vue pas remplir le défilement de la vue?
Le code suivant (appelé dans le viewDidLoad) résultats dans un écran rouge. Je m'attends à ce qu'il soit entièrement écran vert. Pourquoi est-il rouge? Et comment puis-je le faire tout vert?
UIScrollView* scrollView = [UIScrollView new];
scrollView.translatesAutoresizingMaskIntoConstraints = NO;
scrollView.backgroundColor = [UIColor redColor];
[self.view addSubview:scrollView];
UIView* contentView = [UIView new];
contentView.translatesAutoresizingMaskIntoConstraints = NO;
contentView.backgroundColor = [UIColor greenColor];
[scrollView addSubview:contentView];
NSDictionary* viewDict = NSDictionaryOfVariableBindings(scrollView,contentView);
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView]|" options:0 metrics:0 views:viewDict]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollView]|" options:0 metrics:0 views:viewDict]];
[scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[contentView]|" options:0 metrics:0 views:viewDict]];
[scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[contentView]|" options:0 metrics:0 views:viewDict]];
Vous devez vous connecter pour publier un commentaire.
Contraintes avec défilement des vues fonctionnent un peu différemment de ce qu'il fait avec d'autres points de vue. Les contraintes entre des
contentView
et sessuperview
(lescrollView
) sont à lascrollView
'scontentSize
, pas à sonframe
. Cela peut sembler déroutant, mais il est tout à fait utile, ce qui signifie que vous n'aurez jamais à régler lecontentSize
, mais plutôt lacontentSize
ajustera automatiquement pour s'adapter à votre contenu. Ce comportement est décrit dans Note technique TN2154.Si vous souhaitez définir la
contentView
taille de l'écran ou quelque chose comme ça, vous auriez à ajouter une contrainte entre lescontentView
et de la vue principale, par exemple. C'est, certes, l'antithèse de mettre du contenu dans le scrollview, donc j'ai probablement ne le conseille pas, mais il peut être fait.Pour illustrer ce concept, que la taille de
contentView
sera conduit par son contenu, et non par lebounds
de lascrollView
, ajouter une étiquette à votrecontentView
:Maintenant, vous allez voir que la
contentView
(et, par conséquent, lacontentSize
de lascrollView
) sont ajustés pour s'adapter à l'étiquette avec la norme de marges. Et parce que je n'ai pas de spécifier la largeur/hauteur de l'étiquette, qui va ajuster basé sur le texte que vous mettez dans cette étiquette.Si vous voulez le
contentView
également ajuster à la largeur de l'écran principal, vous pouvez redéfinir votreviewDict
comme ça, et ensuite ajouter ces contraintes supplémentaires (en plus de tous les autres, ci-dessus):Il y a un problème connu (bug?) avec multiligne étiquettes dans scrollviews, que, si vous le souhaitez redimensionner en fonction de la quantité de texte, vous devez faire quelques tours de passe-passe, tels que:
J'ai essayé de Rob réponse semble bien, au premier abord. MAIS! si vous avez également activé zoom, cette mise en page automatique de code va obtenir de la manière. Il garde le redimensionnement de la contentView lors des zooms. C'est, si j'ai agrandi (zoomScale > 1), je ne vais pas être capable de faire défiler les pièces en dehors de l'écran.
Après des jours de combats avec mise en page automatique, malheureusement je n'ai pas trouver de solution. En fin de compte, il n'est pas même question (wat? ok, désolé). En fin de compte, je viens de supprimer la mise en forme automatique sur contentView (utiliser une taille fixe contentView), puis dans layoutSubviews, je ajuster la
self.scrollView.contentInset
. (Je suis en utilisant Xcode5, iOS 7)Je sais que ce n'est pas une solution directe à cette question. Mais je veux juste souligner une simple solution de contournement. Il fonctionne parfaitement pour le centrage d'une taille fixe contentView dans un scrollView, avec seulement 2 lignes de code! Espérons qu'il peut aider quelqu'un 😉
En général, la Mise en page Automatique considère le haut, à gauche, en bas et à droite de la vue pour être visible sur les bords. C'est, si vous épinglez une vue sur le bord gauche de son superview, vous êtes vraiment épingler le minimum valeur x de la superview de limites. Changer les limites de l'origine de la superview ne change pas la position de la vue.
La 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.
Les contraintes qui pèsent sur la sous-vues de défilement de la vue doit entraîner une taille à remplir, ce qui est interprété comme la taille du contenu de défilement de la vue. (Ce ne doit pas être confondue avec la intrinsicContentSize méthode utilisée pour la Mise en page Automatique.) Pour la taille le défilement de l'affichage de l'image avec Mise en page Automatique, les contraintes doivent être explicites quant à la largeur et la hauteur de défilement de la vue, ou les bords de défilement de la vue doivent être liés à des points de vue à l'extérieur de sa sous-arborescence.
Notez que vous pouvez faire une sous-vue de défilement de la vue semblent flotter (pas de défilement) sur l'autre défilement de contenu en créant des contraintes entre le point de vue et une vue de l'extérieur, le défilement de l'affichage du sous-arbre, telles que le défilement de la vue superview.
Voici deux exemples de la façon de configurer le défilement de la vue, d'abord de l'approche mixte, et puis la pure approche