ios objective-c uiview autolayout autoresize

ios - cambiar el tamaño de la supervista después de que las subvistas cambien dinámicamente usando el autolayout



objective-c uiview (4)

Usar vistas de contenedor

En el siguiente ejemplo, tengo una imagen de 30x30, y UILabel es más pequeña que la vista que contiene el texto del marcador de posición. Necesitaba que la vista de contenido fuera al menos tan grande como la imagen, pero necesitaba crecer para contener texto de varias líneas.

En formato visual, el contenedor interno se ve así:

H:|-(15.0)-[image(30.0)]-(15.0)-[label]-(15.0)-| V:|[image(30.0)]| V:|[label(>=30.0)]|

Luego, configure la vista que contiene para que coincida con la altura de la etiqueta. Ahora la vista que lo contiene se ajustará al tamaño de la etiqueta.

Como @smileyborg señaló en su respuesta, conectar el contenido rígidamente a la supervista informa al motor de diseño que la vista simple del contenedor debería hacer que crezca.

Rectángulos de alineación amarilla

Si desea los rectángulos de alineación amarilla, agregue -UIViewShowAlignmentRects YES en la lista de argumentos de ejecución de su esquema.

No puedo por el amor de Dios el truco de esta super visión de cambio de tamaño.

Tengo una UIView *superview con 4 UILabels . 2 función como encabezado para los otros 2.

El contenido en los 4 son dinámicos provenientes de la base de datos.

SizeToFit vs SizeThatFits:(CGSize) vs UIView systemLayoutSizeFittingSize: pasando UILayoutFittingCompressedSize o UILayoutFittingExpandedSize .

Uso autolayout programáticamente y he establecido que la altura de la supervista sea igual o superior a un número ficticio.

dónde y cómo utilizo SizeToFit vs sizeThatFits:(CGSize) frente a UIView systemLayoutSizeFittingSize: pasando UILayoutFittingCompressedSize o UILayoutFittingExpandedSize . He leído muchos consejos aquí en la pila pero terminé sin nada.

¿Debo volver a calcular las restricciones para la supervista en algún lugar específico? Maby establece la altura para ser ''@ property` en su clase de controlador y lo elimina y lo lee? Atm. He tratado de poner todo en todos lados y algo más. Todavía obtengo el mismo resultado final de tamaño con la altura ficticia y el texto flotando afuera. Incluso después de configurar clipsToBound en la subvista.

Me estoy rascando el pelo de .. ayuda


Esto casi sigue la respuesta de @smileyborg y viene con un ejemplo concreto.

No describirá todas las restricciones, sino aquellas relacionadas con el cálculo de la altura de los objetos de la interfaz de usuario.

  1. [Etiqueta] Las etiquetas no deben tener una restricción de height fija, en este caso, AutoLayout no cambiará el tamaño de las etiquetas para que se ajusten al texto, por lo que establecer las restricciones de borde es la clave. (flechas verdes)
  2. [Subvista] Los pasos 1 y 3 son muy fáciles de seguir, pero este paso puede malinterpretarse. Como en el caso de las etiquetas, las subvistas no deben tener una restricción de height establecida. Todas las subvistas deben tener un conjunto de restricciones top , ignorando la restricción bottom , lo que puede hacer pensar que activará la excepción de restricción insatisfecha en el tiempo de ejecución, pero no lo hará si establece la restricción bottom para la última subvista. Faltar para hacerlo soplará el diseño. (flechas rojas)

  3. [Supervisión] Establezca todas las restricciones de la forma que necesite, pero preste mucha atención a la restricción de height . Asignarle un valor aleatorio, pero hacerlo opcional, AutoLayout establecerá la altura exactamente para ajustarse a las subvistas. (flechas azules)

Esto funciona perfectamente, no hay necesidad de llamar a ningún método adicional de actualización del diseño del sistema.


Esto se hizo dramáticamente más fácil con la introducción de Stack Views en iOS 9. Use una vista de pila dentro de su vista para contener todo su contenido que cambia de tamaño, y luego simplemente llame

view.setNeedsUpdateConstraints() view.updateConstraintsIfNeeded() view.setNeedsLayout() view.layoutIfNeeded()

después de cambiar tu contenido Entonces puede obtener su nuevo tamaño llamando

view.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize)

si alguna vez necesita calcular el tamaño exacto requerido para una vista.


Si usa Diseño automático, esto es lo que debe hacer:

  1. Asegúrese de no agregar restricciones de ancho y / o altura fijas a ninguna de sus subvistas (dependiendo de qué dimensión desee dimensionar dinámicamente). La idea es permitir que el tamaño del contenido intrínseco de cada subvista determine la altura de la subvista. UILabel viene con 4 restricciones automáticas implícitas que (con menos de la prioridad requerida) intentan mantener el marco de la etiqueta en el tamaño exacto requerido para que se ajuste a todo el texto.

  2. Asegúrese de que los bordes de cada etiqueta estén conectados rígidamente (con restricciones de prioridad requeridas) a los bordes de cada uno y su supervista. Desea asegurarse de que si imagina que una de las etiquetas aumenta de tamaño, esto obligaría a las otras etiquetas a dejar espacio para ella y, lo que es más importante, obligará a la supervista a expandirse también.

  3. Solo agregue restricciones a la supervista para establecer su posición, no el tamaño (al menos, no para la (s) dimensión (es) que desea que dimensione dinámicamente). Recuerde que si establece las restricciones internas correctamente, su tamaño estará determinado por los tamaños de todas las subvistas, ya que sus bordes están conectados a los suyos de alguna manera.

Eso es. No necesita llamar a sizeToFit o sizeToFit systemLayoutSizeFittingSize: para que esto funcione, simplemente cargue sus vistas y configure el texto y así debería ser. El motor de diseño del sistema hará los cálculos para que usted resuelva sus limitaciones. (En todo caso, es posible que deba llamar a setNeedsLayout en la supervista ... pero esto no debería ser obligatorio).