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.
- [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) [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 restriccionestop
, ignorando la restricciónbottom
, 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ónbottom
para la última subvista. Faltar para hacerlo soplará el diseño. (flechas rojas)[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:
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.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.
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).