AutoLayout pour conserver les tailles d'affichage proportionnelles

J'essaie de réaliser ce qui suit:

  • J'ai 2 vues dans mon xib qui doivent restr à 20 pixels du bord (les deux côtés et le dessus)
  • 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 restr relative à la largeur de la vue parent

J'ai lu un tutoriel sur ce sujet et cela fonctionne, mais le problème est que cela nécessite que les deux vues aient la même largeur et les mêmes largeurs de broche, ce que je ne veux pas.

Voici ce que j'ai essayé:

  • Ajouter la contrainte d'espace de début à la vue de gauche à 20 pixels
  • Ajouter la contrainte d'espace supérieur à la vue de gauche à 20 pixels
  • Ajouter la contrainte d'espace supérieur à la vue de droite à 20 pixels
  • Ajouter la contrainte d'espace de tailing à la vue de droite pour être 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 redimensionne pas et la vue de droite remplit l'espace pour garder l'espace horizontal de 20 pixels.

Y a-t-il un moyen de resize les deux vues proportionnellement à l'espace qu'elles devraient remplir?

Voici les captures d'écran de ma layout et de mes contraintes:

Disposition xibDéfinitions de contraintes

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)]> 

Ceci peut être résolu en ajoutant une autre vue fictive ( dummyView ) avec ses contraintes définies sur Fixed width, height et alignées sur centerX de Superview. Ensuite, ajoutez la vue de gauche et la vue de droite Contrainte d'espacement horizontal de dummyView .

entrez la description de l'image icientrez la description de l'image ici

Je suis probablement en retard dans la search d'une solution, mais cela peut être fait très facilement dans IB .

Tout d'abord, ajoutez un UIView et épinglez les quatre bords de l'aperçu.

Ensuite, ajoutez votre première sous-vue et positionnez-la en conséquence (ig: x = 0, y = 0, hauteur = hauteur fixe, largeur = la largeur que vous souhaitez par rapport à l' UIView épinglé aux quatre bords).

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

Voici l'astuce: select la contrainte Equal Widths et éditez le multiplicateur pour get le ratio souhaité (par exemple: 1: 4 si vous voulez que la première sous-vue soit 1/4 du UIView). Répétez les étapes pour la deuxième sous-vue et Tadaaaaaa!

entrez la description de l'image ici

Je suis nouveau sur autolayout mais j'ai rencontré votre question et j'ai pensé que ce serait un bon défi. (C'est ma mise en garde au cas où ce n'est pas la solution idéale!)

Vous devrez append les contraintes de largeur dans le code. J'ai réalisé ceci en ajoutant d'abord les deux vues dans le NIB sans contraintes de largeur. Ce sont les contraintes pour la première vue (à gauche):

entrez la description de l'image ici

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

entrez la description de l'image ici

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

entrez la description de l'image ici

Vous ne pouvez pas supprimer cette contrainte dans IB car cela laisserait une disposition ambiguë (car nous n'avons pas de largeur sur les sous-vues). Cependant, vous pouvez le supprimer dans le code. Premièrement, mettez en place un débouché pour cela et connectez-le dans IB:

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

Ensuite, dans votre vue viewDidLoad du viewDidLoad , vous pouvez le supprimer en utilisant:

 [self.view removeConstraint:self.view2superviewLeadingConstraint]; 

Enfin, ajoutez les contraintes de largeur. La key ici est le paramètre du multiplicateur pour déterminer le pourcentage que vous souhaitez que les largeurs soient basées sur la largeur de la vue globale. Notez également que vous devez définir les parameters constants pour qu'ils correspondent aux totaux avant / arrière définis dans IB:

 NSLayoutConstraint *constraint1 = [NSLayoutConstraint constraintWithItem:self.view1 atsortingbute:NSLayoutAtsortingbuteWidth relatedBy:NSLayoutRelationEqual toItem:self.view atsortingbute:NSLayoutAtsortingbuteWidth multiplier:0.3 constant:-20]; [self.view addConstraint:constraint1]; NSLayoutConstraint *constraint2 = [NSLayoutConstraint constraintWithItem:self.view2 atsortingbute:NSLayoutAtsortingbuteWidth relatedBy:NSLayoutRelationEqual toItem:self.view atsortingbute:NSLayoutAtsortingbuteWidth multiplier:0.7 constant:-40]; [self.view addConstraint:constraint2]; 

Sélectionnez simplement le rapport d'aspect:

entrez la description de l'image ici

Comme d'autres l'ont mentionné, la key est de définir un multiplicateur sur la contrainte "Pin Widths Equally" de sorte que les largeurs des vues finissent par être un multiple les unes des autres. XCode 5.1 devrait append la possibilité de définir ceci dans Interface Builder, mais jusque-là vous avez une autre option en plus de le mettre dans le code. Si vous créez la contrainte "Pin Widths Equally", accédez à l'inspecteur d'identité dans le panneau Utilities sur la droite, puis searchz "User Defined Runtime Atsortingbutes". Ajoutez un nouvel atsortingbut avec la key "multiplicateur", tapez "nombre" et une valeur égale à votre ratio désiré.

Multiplicateur défini en tant qu'attribut d'exécution, comme décrit ci-dessus.

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

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

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

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

Je ne suis pas sûr de savoir à quel point vous êtes familier avec la layout automatique, alors excuses si c'est ce que vous savez déjà:

Lors de l'utilisation de la layout 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 provoque l'avertissement que vous voyez.

Il semble que vous ayez défini plusieurs contraintes pour qu'elles soient explicites. Par exemple, votre vue verte sur la gauche a une contrainte "Largeur points exactement.

Les autres contraintes sont mappées sur la capture d'écran, mais ce qui se passe probablement ici est que ces contraintes explicites causent des problèmes – vous avez des contraintes autoresizing qui indiquent que les vues doivent se dilater ou se contracter pour s'adapter à leur zone disponible, mais ces mêmes vues ont contraintes qui nécessitent d'être une largeur exacte.

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

Dans Interface Builder, faites glisser la vue avec le button droit (juste un peu pour afficher le popup noir).
Dans le menu contextuel, select Aspect Ratio .