web-dev-qa-db-fra.com

Mise en page automatique pour garder les tailles de vue proportionnelles

J'essaie d'atteindre les objectifs suivants:

  • J'ai 2 vues dans mon xib qui doivent rester à 20 pixels du bord (des deux côtés et du haut)
  • Les 2 vues qui doivent être redimensionnées ne sont pas de la même taille
  • Ils doivent être séparés de 20 pixels
  • Leur largeur doit rester relative à la largeur de la vue parent

J'ai lu un tutoriel pour faire exactement cela et cela fonctionne, mais le problème est qu'il nécessite que les deux vues aient la même largeur et la même broche Widths equally, dont je ne veux pas.

Voici ce que j'ai essayé:

  • Ajouter une contrainte d'espace de tête à la vue de gauche de 20 pixels
  • Ajouter une contrainte d'espace supérieure à la vue de gauche de 20 pixels
  • Ajouter une contrainte d'espace supérieure à la vue de droite de 20 pixels
  • Ajouter une contrainte d'espace de queue à la vue de droite de 20 pixels
  • Ajouter une contrainte d'espacement horizontal aux deux vues à 20 pixels

Le problème que je rencontre est que la vue de gauche ne se redimensionne pas et que la vue de droite remplit l'espace pour garder l'espace horizontal de 20 pixels.

Existe-t-il un moyen de redimensionner les deux vues proportionnellement à l'espace qu'elles doivent remplir?

Voici les captures d'écran de ma mise en page et de mes contraintes:

xib LayoutConstraints definitions

Merci!

MODIFIER

Je reçois l'avertissement suivant lorsque j'essaie de faire pivoter mon appareil:

2012-10-11 08:59:00.435 AutolayoutTest[35672:c07] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want.
    Try this: (1) look at each constraint and try to figure out which you don't expect;
    (2) find the code that added the unwanted constraint or constraints and fix it. (Note:  
    If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSLayoutConstraint:0x8a6b2b0 H:[UIView:0x8a6b1d0(170)]>",
    "<NSLayoutConstraint:0x8a68ad0 H:[UIView:0x8a69430(90)]>",
    "<NSLayoutConstraint:0x8a6ba40 H:[UIView:0x8a69430]-(20)-[UIView:0x8a6b1d0]>",
    "<NSLayoutConstraint:0x8a6ba00 H:[UIView:0x8a6b1d0]-(20)-|   (Names: '|':UIView:0x8a6b7e0 )>",
    "<NSLayoutConstraint:0x8a6b940 H:|-(20)-[UIView:0x8a69430]   (Names: '|':UIView:0x8a6b7e0 )>",
    "<NSAutoresizingMaskLayoutConstraint:0x7199aa0 h=--& v=--& V:[UIView:0x8a6b7e0(568)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x8a6b2b0 H:[UIView:0x8a6b1d0(170)]>
48
Simon Germain

Cela peut être résolu en ajoutant une autre vue factice (dummyView) avec ses contraintes définies sur Largeur fixe, hauteur et aligné sur centerX de Superview.Ensuite, ajoutez la vue gauche et la vue droite Contrainte d'espacement horizontal à dummyView.

enter image description hereenter image description here

10
Yatheesha B L

Je suis probablement en retard pour trouver une solution mais cela peut être fait très facilement dans IB .

Tout d'abord, ajoutez un IView et épinglez-le aux quatre bords de la vue d'ensemble.

Ensuite, ajoutez votre première sous-vue et positionnez-le en conséquence (ig: x = 0, y = 0, hauteur = hauteur fixe, largeur = La largeur que vous souhaitez par rapport à IView = nous avons épinglé sur les quatre bords).

Sélectionnez à la fois IView et première sous-vue et ajoutez une contrainte Equal Widths. Bien sûr, cela vous montrera une erreur de positionnement dans la mise en page automatique, mais c'est OK car ce n'est pas (encore) ce que vous voulez.

Voici maintenant l'astuce: sélectionnez la contrainte Equal Widths et modifiez le multiplicateur pour être le rapport que vous voulez (par exemple: 1: 4 si vous voulez que la première sous-vue soit 1/4 de la vue UIV). Répétez les étapes pour la deuxième sous-vue et Tadaaaaaa!

enter image description here

75
Benjamin

Je suis nouveau dans la mise en page automatique, mais je suis tombé sur votre question et j'ai pensé que ce serait un bon défi. (C'est ma mise en garde au cas où ce ne serait pas la solution idéale!)

Vous devrez ajouter les contraintes de largeur dans le code. J'ai atteint cet objectif en ajoutant tout d'abord les deux vues dans la NIB sans contraintes de largeur. Ce sont les contraintes de la première vue (à gauche):

enter image description here

Ce sont les contraintes que j'avais pour la deuxième vue (à droite):

enter image description here

Cela laisse une contrainte supplémentaire que vous ne voulez pas sur la deuxième vue - l'espace principal entre la vue d'ensemble et la deuxième vue, comme indiqué ci-dessous:

enter image description here

Vous ne pouvez pas supprimer cette contrainte dans IB car cela laisserait une disposition ambiguë (car nous n'avons pas de largeurs sur les sous-vues). Cependant, vous pouvez le supprimer dans le code. Tout d'abord, configurez-en une prise et connectez-la dans IB:

@property (nonatomic, strong) IBOutlet NSLayoutConstraint *view2superviewLeadingConstraint;

Ensuite, dans votre viewDidLoad de votre contrôleur de vue, vous pouvez le supprimer en utilisant:

[self.view removeConstraint:self.view2superviewLeadingConstraint];

Enfin, ajoutez les contraintes de largeur. La clé ici est le paramètre multiplicateur pour indiquer quel pourcentage vous souhaitez que les largeurs soient basées sur la largeur de la vue d'ensemble. Notez également que vous devez définir les paramètres constants pour qu'ils soient égaux aux totaux de début/fin configurés dans IB:

NSLayoutConstraint *constraint1 = [NSLayoutConstraint constraintWithItem:self.view1 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:0.3 constant:-20];
[self.view addConstraint:constraint1];

NSLayoutConstraint *constraint2 = [NSLayoutConstraint constraintWithItem:self.view2 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeWidth multiplier:0.7 constant:-40];
[self.view addConstraint:constraint2];
10
Ian L

Sélectionnez simplement le rapport hauteur/largeur:

enter image description here

9
Rémy Virin

Comme d'autres l'ont mentionné, la clé consiste à définir un multiplicateur sur la contrainte "Épaisseur de largeur égale" de sorte que les largeurs de vues finissent par être multiples les unes des autres. XCode 5.1 devrait ajouter la possibilité de définir cela dans Interface Builder, mais d'ici là, vous avez une autre option en plus de le définir dans le code. Si vous créez la contrainte "Épaisseur de largeur égale", accédez à l'inspecteur d'identité dans le panneau Utilitaires à droite, puis recherchez "Attributs d'exécution définis par l'utilisateur". Ajoutez un nouvel attribut avec le chemin de clé "multiplicateur", tapez "nombre" et une valeur égale à votre ratio souhaité.

Multiplier set as a runtime attribute, as described above.

Cela ne se reflétera pas dans Interface Builder, mais s'appliquera lorsque votre vue sera utilisée.

6
JiBB
  1. Supprimez les deux contraintes de largeur dans le code ou réduisez leurs priorités dans IB, sinon vous êtes trop contraint.
  2. Ajoutez une contrainte pour décrire le rapport de largeur entre la vue verte et la vue bleue, dans le code:

    // Assuming the ratio you want is green_view_width : blue_view_width = 1 : 2
    NSLayoutConstraint *c = [NSLayoutConstraint constraintWithItem:greenView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeWidth multiplier:0.5f constant:0.f];
    [commonSuperview addConstraint:c];
    
1
an0

C'est désormais possible dans XCode 6 avec la propriété ratio d'aspect

1
Beninho85

Dans Interface Builder, faites glisser la vue avec le bouton droit (juste un peu pour afficher une fenêtre contextuelle noire).
Dans le menu contextuel, sélectionnez Aspect Ratio.

1
Eugene Braginets

Je ne sais pas à quel point vous êtes familiarisé avec la mise en page automatique, alors veuillez m'excuser s'il s'agit de choses que vous connaissez déjà:

Lors de l'utilisation de la mise en page automatique, il est possible d'affecter plusieurs contraintes à la même propriété. Dans certaines circonstances, ces contraintes peuvent se contredire. C'est ce qui cause l'avertissement que vous voyez.

Il ressemble à partir de la capture d'écran que vous avez publiée, vous avez défini plusieurs contraintes pour être explicite - par exemple, votre vue verte à gauche a une contrainte qui dit "Largeur (90)", ce qui signifie la largeur doit être exactement égale à 90 points.

La capture d'écran ne permet pas de savoir à quoi vos autres contraintes sont mappées, mais ce qui se passe probablement ici, c'est que ces contraintes explicites causent des problèmes - vous avez des contraintes de redimensionnement automatique qui disent que les vues devraient s'étendre ou se contracter pour s'adapter à leur zone disponible, mais ces mêmes vues ont les contraintes qui les obligent à avoir une largeur exacte.

Cela peut être résolu de plusieurs façons - vous pouvez soit supprimer ces contraintes de largeur explicites sur vos vues, soit changer leur priorité (par défaut, les contraintes sont 'obligatoires', mais vous pouvez les changer pour qu'elles soient facultatives).

0
lxt