ios interface-builder ios6 autolayout nslayoutconstraint

ios - AutoLayout para mantener los tamaños de vista proporcionales



interface-builder ios6 (9)

Estoy tratando de lograr lo siguiente:

  • Tengo 2 vistas en mi xib que necesitan permanecer a 20 píxeles del borde (ambos lados y arriba)
  • Las 2 vistas que necesitan cambiar el tamaño no son del mismo tamaño
  • Deben estar separados por 20 píxeles
  • Su ancho debe permanecer en relación con el ancho de la vista principal

Leí un tutorial sobre cómo hacer exactamente eso y funciona, pero el problema es que requiere que ambas vistas tengan el mismo ancho y ancho de pin por Widths equally , lo que no quiero.

Esto es lo que intenté:

  • Agregue restricción de espacio inicial a la vista izquierda para que sea de 20 píxeles
  • Agregue restricción de espacio superior a la vista izquierda para que sea de 20 píxeles
  • Agregue la restricción de espacio superior a la vista derecha para que sea de 20 píxeles
  • Agregue restricción de espacio de cola a la vista derecha para que sea de 20 píxeles
  • Agregue restricción de espaciado horizontal a ambas vistas para que sean 20 píxeles

El problema al que me estoy enfrentando es que la vista izquierda no cambia de tamaño y la vista derecha llena el espacio para mantener el espacio horizontal de 20 píxeles.

¿Hay alguna manera de hacer que las dos vistas cambien de tamaño proporcionalmente al espacio que deberían llenar?

Aquí están las capturas de pantalla de mi diseño y restricciones:

¡Gracias!

EDITAR

Recibo la siguiente advertencia cuando intento rotar mi dispositivo:

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


Ahora es posible en XCode 6 con la propiedad de relación de aspecto


No estoy seguro de lo familiarizado que estás con el diseño automático, así que te pido disculpas si esto es algo que ya sabes:

Al usar el diseño automático, es posible asignar varias restricciones a la misma propiedad. Bajo ciertas circunstancias, estas restricciones pueden contradecirse entre sí. Esto es lo que está causando la advertencia que estás viendo.

Desde la captura de pantalla que publica, parece que estableció varias restricciones para ser explícito; por ejemplo, su vista verde a la izquierda tiene una restricción que dice "Ancho (90)", lo que significa que el ancho debe ser igual a 90 puntos exactamente

No está claro a partir de la captura de pantalla a qué se asignan sus otras restricciones, pero lo que probablemente está sucediendo aquí es que estas restricciones explícitas causan problemas: tiene restricciones de autoevaluación que dicen que las vistas deben expandirse o contraerse para adaptarse a su área disponible, pero esas mismas vistas tienen restricciones que requieren que sean de un ancho exacto.

Esto se puede solucionar de varias maneras: puede eliminar esas restricciones explícitas de ancho en sus vistas, o puede cambiar su prioridad (por defecto las restricciones son ''necesarias'', pero puede cambiarlas para que sean opcionales).


Soy nuevo en el diseño automático, pero encontré tu pregunta y pensé que sería un buen desafío. (¡Esa es mi advertencia en caso de que esta no sea la solución ideal!)

Deberá agregar las restricciones de ancho en el código. Lo logré sumando primero las dos vistas en el NIB sin restricciones de ancho. Estas son las restricciones para la primera vista (izquierda):

Estas son las limitaciones que tuve para la segunda vista (derecha):

Esto deja una restricción adicional que no desea en la segunda vista: espacio inicial entre la supervista y la segunda vista como se muestra a continuación:

No puede eliminar esa restricción en IB ya que dejaría un diseño ambiguo (ya que no tenemos anchos en las subvistas). Sin embargo, puedes eliminarlo en el código. En primer lugar, configure una salida y conéctelo en IB:

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

Luego, en viewDidLoad su controlador de viewDidLoad , puede eliminarlo usando:

[self.view removeConstraint:self.view2superviewLeadingConstraint];

Finalmente, agregue las restricciones de ancho. La clave aquí es el parámetro del multiplicador para indicar en qué porcentaje desea que se basen los anchos en el ancho de la vista superior. También tenga en cuenta que debe establecer los parámetros constantes para igualar los totales iniciales / finales configurados en 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];


  1. Elimine las dos restricciones de ancho en el código o disminuya sus prioridades en IB; de lo contrario, tendrá demasiadas restricciones.
  2. Agregue una restricción para describir la relación de ancho entre la vista verde y azul, en el código:

    // 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];


Como otros han mencionado, la clave es establecer un multiplicador en la restricción "Anchuras Análogas Igualmente" para que el ancho de las vistas termine siendo un múltiplo entre sí. XCode 5.1 debería agregar la capacidad de configurar esto en Interface Builder, pero hasta entonces tienes otra opción además de configurarla en el código. Si crea la restricción "Anchuras Análogas Igualmente", vaya al Inspector de Identidades en el Panel de Utilidades a la derecha, luego busque "Atributos de Tiempo de Ejecución Definidos por el Usuario". Agregue un nuevo atributo con la ruta clave "multiplicador", escriba "número" y valor igual a la proporción deseada.

Esto no se verá reflejado en Interface Builder, pero se aplicará cuando se use su vista.


Esto puede resolverse agregando una vista ficticia más ( dummyView ) con sus restricciones establecidas en Ancho fijo, alto y alineado con el centro X de Superview. Luego agregue la vista izquierda y la vista derecha. Restricción de espaciado horizontal a dummyView .


Probablemente llegue tarde con una solución, pero esto realmente puede hacerse fácilmente en IB .

Primero, agregue un UIView y pin en los cuatro bordes de la supervista.

Luego, agregue su primera subvista y colóquela en consecuencia (ig: x = 0, y = 0, altura = altura fija, ancho = El ancho que desea en relación con la UIView que fijamos en los cuatro bordes).

Seleccione tanto UIView como la primera subvista y agregue una restricción de Anchos iguales . Por supuesto, esto le mostrará un error en el posicionamiento en el diseño automático, pero eso está bien porque esto no es (todavía) lo que quiere.

Ahora viene el truco: seleccione la restricción Igual Anchos y edite el Multiplicador para que sea la relación que desea (por ejemplo: 1: 4 si desea que la primera subvista sea 1/4 de UIView). Repite los pasos para la segunda subvista y Tadaaaaaa!


Simplemente seleccione la relación de aspecto:


En Interface Builder, arrastre la vista con el botón derecho (solo un poco para mostrar una ventana emergente negra).
En el menú emergente, seleccione Aspect Ratio .