Reproducción automática de cacao: prioridad de resistencia de compresión de contenido frente a contenido


643

No puedo encontrar una respuesta clara en la documentación de Apple con respecto a Cocoa Autolayout sobre la diferencia entre el abrazo de contenido y la resistencia a la compresión.

¿Alguien puede explicar sus usos y diferencias?


49
Uno de los principales misterios de la vida es por qué no lo llamaron simplemente "resistencia de expansión". Las dos cualidades no son más que "resistencia a la expansión" y "resistencia a la compresión" . La terminología de "abrazar" es una locura.
Fattie

3
Si tienes demasiado espacio, entonces content-hugging: lucharías contra tener espacio en blanco. Simplemente forzaría la vista a rodearlo. Pero si no tienes demasiado espacio y, en cambio, tienes muy poco lugar, entonces content-compressions-resistancelucharías contra tu visión de no poder mostrar todo su contenido, por ejemplo, las etiquetas se truncarían.
Miel

Respuestas:


1319

Un resumen rápido de los conceptos:

  • Abrazando => el contenido no quiere crecer
  • Resistencia a la compresión => el contenido no quiere reducirse

Ejemplo:

Digamos que tienes un botón como este:

[       Click Me      ]

y has fijado los bordes a una supervista más grande con prioridad 500.

Entonces, si la prioridad de Abrazo> 500 se verá así:

[Click Me]

Si Abrazando prioridad <500 se verá así:

[       Click Me      ]

Si la supervista ahora se reduce, entonces, si la prioridad de Resistencia a la compresión> 500, se verá así

[Click Me]

De lo contrario, si la Resistencia a la compresión tiene prioridad <500, podría verse así:

[Cli..]

Si no funciona así, entonces probablemente tengas otras restricciones que están arruinando tu buen trabajo.

Por ejemplo, podría tenerlo clavado en la supervista con prioridad 1000. O podría tener una prioridad de ancho. Si es así, esto puede ser útil:

Editor> Tamaño para ajustar contenido


37
¿Qué pasa si abrazar prioridad == 500?
bradley.ayers

1
Me supongo (pero eso no es por lo general una buena idea) que sería tratado como> 500 como el comportamiento típico de redondeo. Aunque no lo he probado.
Joshua Nozzi

lo más probable es que reciba la advertencia "No se pueden cumplir simultáneamente las restricciones" en tiempo de ejecución
Max Desiatov

8
@ bradley.ayers Para el comentario de MaxDesyatov, eso solo sucederá si tiene restricciones conflictivas con la prioridad requerida (1000). Si entran en conflicto dos restricciones de menor prioridad, la solución es ambigua, por lo que el motor de diseño automático solo elegirá una solución válida y eso es lo que verá (sin advertencias). Obviamente, esto no es bueno, porque ahora depende de la implementación interna del motor de Diseño automático elegir cómo se ve su diseño, y en teoría, ¡esto podría cambiar de una versión de iOS a la siguiente!
smileyborg

La prioridad predeterminada de ajuste de contenido es 250, y la resistencia predeterminada de compresión de contenido es 750. Entonces, ¿por qué usar 500?
ZYiOS

292

Eche un vistazo a este video tutorial sobre Autolayout , lo explican cuidadosamente

ingrese la descripción de la imagen aquí


1
@fatuhoku puede que puedes volver a intentarlo, este video es gratis
onmyway133

31
La discusión sobre los abrazos contra la resistencia comienza aproximadamente a las 13:15 en el video.
Carl Smith

1
@ onmyway133 este es un video perfecto, pero desafortunadamente no hay ningún ejemplo de cómo lo usa Ray.
Matrosov Alexander

@MatrosovAlexander Creo que un ejemplo muy práctico sería la altura de celda dinámica con Autolayout fantageek.com/1468/…
onmyway133

1
Él muestra cómo usar la resistencia a la compresión a las 18:05
Brent Faust

187

ingrese la descripción de la imagen aquí

fuente: @mokagio

Tamaño de contenido intrínseco : bastante explicativo, pero las vistas con contenido variable son conscientes de cuán grande es su contenido y describen el tamaño de su contenido a través de esta propiedad. Algunos ejemplos obvios de vistas que tienen tamaños de contenido intrínsecos son UIImageViews, UILabels, UIButtons.

Prioridad de abrazo de contenido : cuanto mayor es esta prioridad, más se resiste una vista a crecer más que su tamaño de contenido intrínseco.

Prioridad de resistencia de compresión de contenido : cuanto mayor sea esta prioridad, más resistirá una vista a reducirse a un tamaño de contenido intrínseco menor.

Consulte aquí para obtener más explicaciones: MAGIA DE DISEÑO AUTOMÁTICO: PRIORIDADES DE TAMAÑO DEL CONTENIDO


La ilustración es bonita pero engañosa por decir lo menos. El hombre superior debería decir "No voy a (dejarme crecer)". La vista secundaria define por sí misma que no quiere crecer a través de su comportamiento de abrazo de contenido. No hay fuerza exógena (como las manos ilustradas) que impiden su crecimiento. Eso es una gran diferencia.
Manuel

66
Estoy votando esto solo porque me encanta la ilustración.
James Bucanek

3
Es por eso que me encanta Stack Overflow ... La descripción de Snowcrash más esta ilustración de mokagio = la mejor explicación de estas propiedades en cualquier lugar (incluida la documentación de Apple).
Kal

40

Digamos que tiene un botón con el texto "Haga clic en mí". ¿Qué ancho debe tener ese botón?

Primero, definitivamente no quieres que el botón sea más pequeño que el texto. De lo contrario, el texto se recortaría. Esta es la prioridad de resistencia a la compresión horizontal.

En segundo lugar, no desea que el botón sea más grande de lo necesario. Un botón que se parece a esto, [Click Me], obviamente es demasiado grande. Desea que el botón "abrace" su contenido sin demasiado relleno. Este es el contenido horizontal que abarca la prioridad. Para un botón, no es tan fuerte como la prioridad de resistencia de compresión horizontal.


19

Si view.intrinsicContentSize.width != NSViewNoIntrinsicMetric, entonces el diseño automático crea una restricción especial de tipo NSContentSizeLayoutConstraint. Esta restricción actúa como dos restricciones normales:

  • una restricción que requiere view.width <= view.intrinsicContentSize.widthcon la prioridad de abrazo horizontal, y
  • una restricción que requiere view.width >= view.intrinsicContentSize.widthcon la prioridad de resistencia de compresión horizontal.

En Swift, con los nuevos anclajes de diseño de iOS 9, puede configurar restricciones equivalentes como esta:

let horizontalHugging = view.widthAnchor.constraint(
    lessThanOrEqualToConstant: view.intrinsicContentSize.width)
horizontalHugging.priority = view.contentHuggingPriority(for: .horizontal)

let horizontalCompression = view.widthAnchor.constraint(
    greaterThanOrEqualToConstant: view.intrinsicContentSize.width)
horizontalCompression.priority = view.contentCompressionResistancePriority(for: .horizontal)

De manera similar, si view.intrinsicContentSize.height != NSViewNoIntrinsicMetric, entonces el diseño automático crea una NSContentSizeLayoutConstraintque actúa como dos restricciones en la altura de la vista. En código, se verían así:

let verticalHugging = view.heightAnchor.constraint(
    lessThanOrEqualToConstant: view.intrinsicContentSize.height)
verticalHugging.priority = view.contentHuggingPriority(for: .vertical)

let verticalCompression = view.heightAnchor.constraint(
    greaterThanOrEqualToConstant: view.intrinsicContentSize.height)
verticalCompression.priority = view.contentCompressionResistancePriority(for: .vertical)

Puede ver estas NSContentSizeLayoutConstraintinstancias especiales (si existen) imprimiendo view.constraintsdespués de que se haya ejecutado el diseño. Ejemplo:

label.constraints.forEach { print($0) }

// Output:
<NSContentSizeLayoutConstraint:0x7fd82982af90 H:[UILabel:0x7fd82980e5e0'Hello'(39)] Hug:250 CompressionResistance:750>
<NSContentSizeLayoutConstraint:0x7fd82982b4f0 V:[UILabel:0x7fd82980e5e0'Hello'(21)] Hug:250 CompressionResistance:750>

1
si no es así: let verticalCompression = view.heightAnchor.constraint (greaterThanOrEqualToConstant: view.intrinsicContentSize.height)
mc_plectrum

1
Sí, cometí un error de copiar / pegar. Lo he corregido. Gracias por hacérmelo saber.
rob mayoff

15

Las prioridades de Resistencia de compresión de contenido y compresión de contenido funcionan para elementos que pueden calcular su tamaño intrínsecamente dependiendo de los contenidos que ingresan.

De los documentos de Apple :

ingrese la descripción de la imagen aquí


plus1 para la imagen (Y)
Noor Ali Butt

Estoy confundido. Para una vista de texto que no tiene habilitado el desplazamiento. ¿Eso significa que por usuario que escriba el tamaño intrínseco cambiaría?
Miel

@Honey Creo que con las restricciones correctas establecidas y el desplazamiento deshabilitado, la vista de texto debería ser capaz de determinar la altura intrínseca.
dev gr

Eso no respondió mi pregunta. ¿Quiere decir que si escribo mucho, más que el tamaño actual de textView ... el textView se expande automáticamente y cambia el tamaño intrínseco?
Miel

Inténtalo tú mismo. Otorgue a textview un ancho fijo, desactive el desplazamiento y compruebe el comportamiento deseado. Consulte stackoverflow.com/a/21287306/1526629 para obtener más respuestas.
dev gr

11

El Content hugging priorityes como una banda de goma que se coloca alrededor de una vista. Cuanto mayor es el valor de prioridad, más fuerte es la banda elástica y más quiere abrazar a su tamaño de contenido. El valor de prioridad se puede imaginar como la "fuerza" de la banda elástica

Y Content Compression Resistancees decir, cuánto se "resiste" una vista cada vez más pequeña. La vista con mayor valor de prioridad de resistencia es la que resistirá la compresión.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.