Ambigüedad del tamaño del contenido desplazable de UIScrollView

Resuelto Wirsing asked hace 54 años • 35 respuestas

Compañeros desarrolladores, tengo problemas con AutoLayout en Interface Builder (Xcode 5/iOS 7). Es muy básico e importante, así que creo que todos deberían saber cómo funciona correctamente. Si esto es un error en Xcode, ¡es crítico!

Entonces, cada vez que tengo una jerarquía de vistas como esta, tengo problemas:

>UIViewController
>> UIView
>>>UIScrollView
>>>>UILabel (or any other comparable UIKit Element)

UIScrollView tiene restricciones sólidas, por ejemplo, 50 px de cada lado (no hay problema). Luego agrego una restricción de espacio superior a UILabel (no hay problema) (e incluso puedo fijar la altura/ancho de la etiqueta, no cambia nada, pero debería ser innecesario debido al tamaño intrínseco de la etiqueta)

El problema comienza cuando agrego una restricción final a UILabel:

Por ejemplo, espacio final para: Supervisión es igual a: 25

Ahora aparecen dos advertencias y no entiendo por qué:

A) Ambigüedad en el tamaño del contenido desplazable (la vista de desplazamiento tiene un alto/ancho de contenido desplazable ambiguo)

B) Vistas fuera de lugar (Etiqueta esperada: x= -67 Real: x= 207

Hice este ejemplo mínimo en un proyecto nuevo que puedes descargar y adjunté una captura de pantalla. Como puede ver, Interface Builder espera que la etiqueta se encuentre fuera del límite de UIScrollView (el rectángulo discontinuo naranja). Actualizar el marco de la etiqueta con la herramienta Resolver problemas la mueve allí mismo.

Tenga en cuenta: si reemplaza UIScrollView con UIView, el comportamiento es el esperado (el marco de la etiqueta es correcto y de acuerdo con la restricción). Parece que hay un problema con UIScrollView o me estoy perdiendo algo importante.

Cuando ejecuto la aplicación sin actualizar el marco de la etiqueta como lo sugiere IB, se coloca bien, exactamente donde se supone que debe estar y UIScrollView se puede desplazar. Si actualizo el marco, la etiqueta no está a la vista y UIScrollView no se desplaza.

¡Ayúdame Obi-Wan Kenobi! ¿Por qué el diseño ambiguo? ¿Por qué esa visión fuera de lugar?

Puede descargar el proyecto de muestra aquí e intentar descubrir qué está pasando: https://github.com/Wirsing84/AutoLayoutProblem

Ilustración del problema en Interface Builder

Wirsing avatar Jan 01 '70 08:01 Wirsing
Aceptado

Actualizado

Hoy en día, Apple se dio cuenta del problema que resolvimos hace muchos años (lol_face) y proporciona una Guía de diseño de contenido y una Guía de diseño de marcos como parte del UIScrollView. Por lo tanto, debe seguir los siguientes pasos:

  1. Igual que la respuesta original a continuación;

  2. Para esto contentView, establezca los márgenes superior, inferior, izquierdo y derecho en 0 y fijelos en la Guía de diseño de contenido de la vista de desplazamiento;

  3. Ahora establezca la contentViewaltura de igual a la altura de la Guía de diseño del marco . Haz lo mismo con el ancho;

  4. Finalmente, establezca la prioridad de las restricciones de igual altura en 250 (si necesita que la vista se desplace verticalmente, el ancho se desplace horizontalmente).

Finalizado .

Ahora puede agregar todas sus vistas en ese archivo contentViewy el contentSizetamaño del archivo scrollViewcambiará automáticamente de acuerdo con el archivo contentView.

No olvide establecer la restricción desde la parte inferior del último objeto contentViewhasta el contentViewmargen.

Original [obsoleto]

Entonces lo resolví de esta manera:
  1. Dentro del UIScrollView add a UIView(podemos llamarlo contentView);

  2. En esto contentView, establezca los márgenes superior, inferior, izquierdo y derecho en 0 (por supuesto, de scrollViewcuál es el superView); Configure también alinear el centro horizontal y verticalmente ;

Matteo Gobbi avatar Dec 01 '2014 11:12 Matteo Gobbi

Xcode 11+

La forma más sencilla usando autolayout:

  1. Agréguelo UIScrollViewy fíjelo 0,0,0,0a la supervisión (o al tamaño que desee)
  2. Agregue un contenedor de UIViewtipo dentro de ScrollView, fíjelo 0,0,0,0a los 4 lados y céntrelo horizontallyy vertically.
  3. En el inspector de tamaño del contenedor, cambie bottomy align center Ypriorice a 250. (para cambio de desplazamiento horizontal trailingy align center X)
  4. Agregue todas las vistas que necesite en dicho contenedor (UIView). No olvide establecer la restricción inferior en la vista más baja.
  5. Seleccione UIScrollView, seleccione el inspector de tamaño y anule la selección Content Layout Guides.
Đorđe Nilović avatar May 04 '2017 14:05 Đorđe Nilović

Xcode 11+, Rápido 5

Si se pregunta por qué todas las respuestas ya no funcionan, asegúrese de haber fijado la vista de contenido (la que colocó dentro de la vista de desplazamiento) en la Guía de diseño de contenido de la vista de desplazamiento y NO en la Guía de diseño de marco.

Los bordes de la vista de contenido (inicial, final, superior, inferior) no deben fijarse como los iniciales de la imagen - a la Guía de diseño de marcos

Así no

pero así: a la Guía de diseño de contenido.

Seleccione Guía de diseño de contenido del menú desplegable

ingrese la descripción de la imagen aquí

Y entonces la mayoría de las respuestas funcionarán para usted.

El enfoque más simple ahora es el siguiente:

  1. Poner la vista de desplazamiento en la vista raíz
  2. Anclar todos los lados de la vista de desplazamiento a la supervista
  3. Tome otra UIView (la llamaremos vista de contenido) y colóquela dentro de la vista de desplazamiento
  4. Fije todos los lados de la vista de contenido para desplazarse por la Guía de diseño de contenido de la vista
  5. Fije el ancho de la vista de contenido para que sea igual a la Guía de diseño de marcos de la vista de desplazamiento
  6. Corrija la altura de la vista de contenido de la forma que desee (en el siguiente ejemplo utilicé solo una restricción de altura constante)

En general, su estructura en la implementación más simple se verá así

ingrese la descripción de la imagen aquí

WantToKnow avatar Oct 10 '2019 14:10 WantToKnow

Me tomó un tiempo localizar este error; inicialmente intenté fijar el tamaño de ScrollView pero el mensaje de error dice claramente "tamaño del contenido". Me aseguré de que todo lo que fijé desde la parte superior de ScrollView también estuviera fijado en la parte inferior. De esa manera, ScrollView puede calcular la altura de su contenido encontrando la altura de todos los objetos y restricciones. Esto resolvió la altura ambigua del contenido, el ancho es bastante similar... Inicialmente tenía la mayoría de las cosas X centradas en ScrollView, pero también tenía que fijar los objetos al costado de ScrollView. No me gusta esto porque el iPhone6 ​​puede tener una pantalla más ancha pero eliminará el error de "ancho de contenido ambiguo".

self.name avatar Oct 01 '2013 20:10 self.name

Debe crear una UIViewsubvista como UIScrollViewse describe a continuación:

  • UIViewController
  • UIView'Vista principal'
    • UIScrollView
      • UIView'Vista de contenedor'
        • [Tu contenido]

El segundo paso es hacer las UIScrollViewrestricciones. Hice esto con las restricciones superior, inferior, inicial y final de su superView.

Luego agregué las restricciones para el contenedor de UIScrollViewy aquí es donde comienza el problema. Cuando pones las mismas restricciones (superior, inferior, inicial y final), el Storyboard muestra un mensaje de advertencia:

"Tiene un ancho de contenido desplazable ambiguo" y "Tiene un alto de contenido desplazable ambiguo"

Continue with the same constraints above, and just add the constraints Equal Height and Equal Width to your Container View in relation to the Main View and not to your UIScrollView. In other words the Container View's constraints are tied to the UIScrollView's superview.

After that you will not have warnings in your Storyboard and you can continue adding the constraints for your subviews.

Thiago Monteiro avatar Oct 29 '2014 21:10 Thiago Monteiro