Compañeros de desarrollo, estoy teniendo 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 esto correctamente. Si esto es un error en Xcode, ¡es crítico!
Entonces, cada vez que tengo una jerarquía de vistas como esta me encuentro con problemas:
>UIViewController
>> UIView
>>>UIScrollView
>>>>UILabel (or any other comparable UIKit Element)
El UIScrollView tiene restricciones sólidas, por ejemplo, 50 px de cada lado (no hay problema). Luego agrego una restricción de espacio superior al UILabel (no hay problema) (e incluso puedo fijar el alto / 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 a: Supervisión igual: 25
Ahora ocurren dos advertencias, y no entiendo por qué:
A) Ambigüedad de tamaño de contenido desplazable (la vista de desplazamiento tiene altura / anchura 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 asiente fuera del límite de UIScrollView (el rectángulo punteado naranja). La actualización del marco de la etiqueta con la herramienta Resolver problemas lo mueve allí mismo.
Tenga en cuenta: si reemplaza el UIScrollView con un 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, está bien ubicado, exactamente donde se supone que debe estar y el UIScrollView es desplazable. Si actualizo el marco, la etiqueta está fuera de la vista y el UIScrollView no se desplaza.
¡Ayúdame, Obi-Wan Kenobi! ¿Por qué el diseño ambiguo? ¿Por qué la vista fuera de lugar?
Puede descargar el proyecto de muestra aquí y probar si puede descubrir qué está pasando: https://github.com/Wirsing84/AutoLayoutProblem
UIScrollView
directamente. En lugar de usarUICollectionView
oUITableView
tanto como sea posible, ¡casi todo es posible con estos elementos y también brinda simplicidad, legibilidad y reutilización!Respuestas:
Así que lo resolví de esta manera:
Dentro del
UIScrollView
complemento aUIView
(podemos llamarlocontentView
);En esto
contentView
, establezca los márgenes superior, inferior, izquierdo y derecho en 0 (por supuesto, delscrollView
cual es elsuperView
); Establecer también alinea el centro horizontal y verticalmente ;Terminado .
Ahora puede agregar todos sus puntos de vista en el que
contentView
, y elcontentSize
de lascrollView
se ajustará automáticamente de acuerdo con elcontentView
.Actualizar:
Algunos casos especiales están cubiertos por este video publicado por @Sergio en los comentarios a continuación.
fuente
Este error me llevó un tiempo rastrear, inicialmente intenté fijar el tamaño del ScrollView pero el mensaje de error dice claramente "tamaño del contenido". Me aseguré de que todo lo que anclaba desde la parte superior de ScrollView también estuviera fijado en la parte inferior. De esa forma, ScrollView puede calcular la altura de su contenido al encontrar la altura de todos los objetos y restricciones. Esto resolvió la altura del contenido ambiguo, 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 a un lado de ScrollView. No me gusta esto porque el iPhone6 podría tener una pantalla más ancha, pero eliminará el error 'ancho de contenido ambiguo'.
fuente
Xcode 11+
La forma más sencilla de usar
autolayout
:UIScrollView
y0,0,0,0
anclarlo a la supervista (o el tamaño deseado)UIView
ScrollView, fíjelo0,0,0,0
a los 4 lados y céntrelohorizontally
yvertically
.bottom
yalign center Y
prioridad a 250. (para cambio de desplazamiento horizontaltrailing
yalign center X
)UIScrollView
, seleccione el inspector de tamaño y deseleccioneContent Layout Guides
.fuente
Es la respuesta a mi pregunta con respuesta propia UIScrollView + Vista centrada + Tamaño de contenido desplazable ambiguo + muchos tamaños de iPhone .
¡Pero también cubre completamente su caso!
Entonces, aquí está el estado inicial para el caso más simple:
Has ambiguous scrollable content width
yHas ambiguous scrollable content height
.Todo lo que tenemos que hacer es:
Importante: debe agregar restricciones finales y / o inferiores . No es "líder y superior", ¡no funciona!
Puede verificarlo en mi proyecto de ejemplo , que muestra cómo solucionar este problema.
PD
Según la lógica, esta acción debería causar "restricciones conflictivas". ¡Pero no!
No sé por qué funciona y cómo Xcode detecta qué restricción tiene más prioridad (porque no tengo la prioridad de estas restricciones explícitamente). Estaré agradecido si alguien explica, por qué funciona en los comentarios a continuación.
fuente
Xcode 11+, Swift 5
Si se pregunta por qué todas las respuestas ya no funcionan, asegúrese de haber anclado la vista de contenido (la que ha colocado dentro de la vista de desplazamiento) a la Guía de diseño de contenido de la vista de desplazamiento y NO a la Guía de diseño de marco.
Los bordes de la vista de contenido (inicial, posterior, superior, inferior) no deben fijarse como los principales en la imagen: a la Guía de diseño de cuadros
pero así: a la Guía de diseño de contenido.
Y luego la mayoría de las respuestas funcionarán para usted.
El enfoque más simple ahora es así:
En general, su estructura en la implementación más simple se verá así
fuente
UIView
Debe crear una como una subvista de laUIScrollView
que se describe a continuación:UIViewController
UIView
'Vista principal'UIScrollView
UIView
'Vista de contenedor'El segundo paso es hacer las
UIScrollView
restricciones. Hice esto con las restricciones superior, inferior, inicial y final de su superView.Luego agregué las restricciones para el contenedor de
UIScrollView
y aquí es donde comienza el problema. Cuando coloca las mismas restricciones (arriba, abajo, al principio y al final), el Guión gráfico muestra un mensaje de advertencia:"Tiene ancho de contenido desplazable ambiguo" y "Tiene altura de contenido desplazable ambiguo"
Continúe con las mismas restricciones anteriores, y solo agregue las restricciones
Equal Height
yEqual Width
a su Vista de contenedor en relación con la Vista principal y no con suUIScrollView
. En otras palabras, las restricciones de la Vista de contenedor están vinculadas a laUIScrollView
supervista de.Después de eso, no tendrá advertencias en su Guión gráfico y puede continuar agregando las restricciones para sus subvistas.
fuente
Tuve el mismo problema. Desmarca esta casilla de verificación. Ya que está configurando el tamaño del contenido en el código.
fuente
Finalmente lo descubrí, espero que sea más fácil de entender.
A menudo puede omitir esa advertencia agregando una vista de UIV base a la vista de desplazamiento como una "vista de contenido", como se mencionó, y que tenga el mismo tamaño que su vista de desplazamiento y, en esta vista de contenido, configure estos 6 parámetros.
Como puede ver, ¡necesita 6 parámetros totales! Lo cual ... en circunstancias normales, está duplicando 2 restricciones, pero esta es la forma de evitar este error del guión gráfico.
fuente
Sé que puedo llegar tarde, pero la próxima solución resuelve este tipo de problemas sin código adicional , solo usando guiones gráficos:
Para su vista de contenido, debe establecer restricciones para los espacios iniciales / finales / superiores / inferiores para la vista de desplazamiento y esto no cambiará el marco de la vista de contenido , de esta manera:
Por supuesto, debe crear restricciones adicionales para la vista de contenido para que la vista de desplazamiento pueda conocer el tamaño del contenido. Por ejemplo, ajuste la altura fija y el centro x.
Espero que esto ayude.
fuente
Para mí, agregar un
contentView
realmente no funcionó como se sugiere. Además, crea una sobrecarga debido a la vista agregada (aunque no considero que esto sea un gran problema). Lo que funcionó mejor para mí fue simplemente desactivar la verificación de ambigüedad para miscrollView
. Todo se presenta bien, así que creo que está bien en casos simples como el mío. Pero tenga en cuenta que si hay otras restricciones para suscrollView
descanso, el Generador de interfaces no le advertirá más al respecto.fuente
Eche un vistazo a este tutorial realmente rápido y preciso sobre cómo hacer que la vista de desplazamiento funcione y se pueda desplazar completamente con el diseño automático. Ahora, lo único que todavía me deja perplejo es por qué el tamaño del contenido de la vista de desplazamiento siempre es más grande de lo necesario.
http://samwize.com/2014/03/14/how-to-use-uiscrollview-with-autolayout/
fuente
Vea a continuación: vista de contenido en vista de desplazamiento vertical y horizontal centralizada. tiene un error de ambigüedad, asegúrese siempre de que dos agregados en la vista de desplazamiento desde su vista de contenido es 1). espacio de botón al contenedor. 2) espacio final a restricción que se resalta en la captura de pantalla,
estas restricciones significan en el desplazamiento cuánto se puede desplazar después de la altura o el ancho de la vista de contenido.
Te puede ayudar.
fuente
Resolví este tipo de problema para mi vista usando "Resolver problemas de diseño automático"> "Agregar restricciones faltantes" para la Vista seleccionada
Las siguientes dos restricciones resuelven mi problema:
en el que: final, inferior son los finales, inferior de UIScrollView
fuente
Usando contentView (
UView
) como en el interior de contenedoresUIScrollView
, se adhieren a los bordes (top
,bottom
,trailing
,leading
) de supervista (UIScrollView
) ycontentView
deben tenerequalwidth
yequalheight
a supervista. Esas son restricciones. Y llamada de método:Problemas resueltos para mí.
fuente
Enfoque Swift 4+:
1) Establezca los márgenes superior, inferior, izquierdo y derecho de UIScrollView en 0
2) Dentro del UIScrollView, agregue un UIView y establezca los márgenes superior, inferior, inicial y posterior a 0 (igual a los márgenes de UIScrollView).
3) La parte más importante es establecer el ancho y la altura, donde la restricción de altura debe tener una prioridad baja .
fuente
La respuesta de @Matteo Gobbi es perfecta, pero en mi caso, la vista de desplazamiento no se puede desplazar, elimino " alinear centro Y " y agrego " altura> = 1 ", la vista de desplazamiento se desplazará
fuente
Las personas que luchan con uiscrollview que no se desplazan solo configuran la restricción inferior de su vista de contenido con el diseño inferior de su última vista (que está dentro de su vista de contenido). No olvide eliminar la restricción Y central.
Descanse todas las restricciones son las mismas que se definieron anteriormente. La vista de desplazamiento solo se preocupa por obtener la altura máxima de su vista de contenido, y la estamos configurando como la restricción inferior de la última vista, lo que significa que la vista de desplazamiento cambiará automáticamente su compensación de contenido.
En mi caso, la última vista era UILable con ninguna propiedad de líneas = 0 (que ajusta automáticamente su altura dependiendo de su contenido) para que aumente dinámicamente la altura de uilable y, finalmente, nuestra área desplazable aumenta debido a que el diseño inferior de uilable está alineado con la parte inferior de nuestra vista de contenido, lo que obliga a scrollview a aumentar su desplazamiento de contenido.
fuente
Hice un video en
youtube Scroll StackViews usando solo Storyboard en Xcode
Creo que 2 tipos de escenarios pueden aparecer aquí.
La vista dentro de scrollView -
UIView
. ej. )UIStackView
. ej. )Para una vista desplazable verticalmente en ambos casos, debe agregar estas restricciones:
4 restricciones desde arriba, izquierda, abajo y derecha.
Ancho igual a vista de desplazamiento (para dejar de desplazarse horizontalmente)
No necesita ninguna otra restricción para las vistas que tienen su propia altura de contenido intrínseco.
Para las vistas que no tienen una altura de contenido intrínseca, debe agregar una restricción de altura. La vista se desplazará solo si la restricción de altura es mayor que la altura de scrollView.
fuente
Salida:
fuente
En mi caso, recibí el problema de tamaño de contenido incorrecto y ambigüedad de tamaño de contenido en iPad, pero estaba funcionando en el caso de iPhone. He realizado los siguientes cambios en el guión gráfico para resolver el problema.
fuente
El desplazamiento vertical
fuente
Lo que hice fue crear una vista de contenido separada como se muestra aquí.
La vista de contenido es de forma libre y puede tener todas las subvistas agregadas con sus propias restricciones en relación con contentView.
El UIScrollView se agrega al controlador de vista principal.
Programáticamente agrego el contentView que está vinculado a través de IBOutlet a la clase y establezco el contentView de UIScrollView.
fuente
Recibía el mismo error ... he hecho lo siguiente
Ahora agregue líder / final / superior / inferior para scrollView (2) y luego UIView (3).
Seleccione Ver (1) y Ver (3) establecer igual altura y peso .. se resolvió mi problema.
He hecho el video que ayudará:
https://www.youtube.com/watch?v=s-CPN3xZS1A
fuente
[probado en XCode 7.2 y para iOS 9.2]
Lo que suprimió los errores y advertencias de Storyboard para mí fue establecer el tamaño intrínseco de la vista de desplazamiento y la vista de contenido (en mi caso, una vista de pila) en Placeholder . Esta configuración se encuentra en el inspector de tamaño en Storyboard. Y dice: establecer un tamaño de contenido intrínseco en tiempo de diseño solo afecta a una vista mientras se edita en Interface Builder. La vista no tendrá este tamaño de contenido intrínseco en tiempo de ejecución.
Entonces, supongo que no nos vamos a equivocar al configurar esto.
Nota: En el guión gráfico, he anclado todos los bordes de scrollview a la supervista y todos los bordes de stackview a la vista de desplazamiento. En mi código, configuré las traducciones de AutoresizingMaskIntoConstraints como falsas tanto para la vista de desplazamiento como para la vista de pila. Y no he mencionado un tamaño de contenido. Cuando la vista de pila crece dinámicamente, las restricciones establecidas en el guión gráfico aseguran que la pila sea desplazable.
La advertencia del guión gráfico me estaba volviendo loco y no quería centrar las cosas horizontal o verticalmente solo para suprimir la advertencia.
fuente
Si alguien está teniendo un comportamiento en el que nota la barra de desplazamiento en los desplazamientos correctos pero el contenido no se mueve, este hecho probablemente valga la pena considerar:
Eso es de la documentación de Apple . Por ejemplo, si accidentalmente fijó su Etiqueta / Botón / Img / Vista superior a la vista fuera del área de desplazamiento (¿Tal vez un encabezado o algo justo encima de la Vista de desplazamiento?) En lugar de la Vista de contenido, congelaría toda su Vista de contenido en su lugar.
fuente
Como se mencionó en las respuestas anteriores, debe agregar una vista personalizada dentro de la vista de desplazamiento:
Agregue todas sus subvistas a la vista de contenido. En algún momento verá que una vista de contenido de desplazamiento tiene una advertencia de tamaño de contenido ambigua, debe seleccionar la vista de contenido y hacer clic en el botón "Resolver problemas de diseño automático" (en la esquina inferior derecha del diseño IB), y seleccione "Agregar falta "restricciones".
A partir de ahora, cuando ejecute el proyecto, la vista de desplazamiento actualizará automáticamente su tamaño de contenido, sin necesidad de código adicional.
fuente
En mi caso, una vista de desplazamiento de desplazamiento horizontal, también necesitaba agregar restricciones de ancho y alto para cada elemento secundario de la vista de desplazamiento, aunque la nota técnica de Apple no lo dice.
fuente
Establezca el tamaño de ViewController (el que tiene el UIScrollView) en Forma libre en el inspector de tamaño en Interface Builder y todo debería funcionar.
Configuración de forma libre en el inspector de tamaño en Interface Builder para el controlador UIViewcontroller
fuente
Si todavía tiene problemas con UIScrollView, simplemente desactive las Guías de diseño de contenido (seleccione su ScrollView en xcode Interface Builder -> elija el inspector de tamaño en el panel derecho -> deseleccione 'Guías de diseño de contenido') O intente estos pasos: xcode 11 diseños de vista de desplazamiento - Puede ser útil para un nuevo estilo de diseño. Funciona bien en macOS 10.15.2, Xcode 11.3.1, para 05.02.2020
ver captura de pantalla
fuente
Usando Autolayout
Agregue su vista de desplazamiento dentro de una vista bien definida y luego agregue la vista de pila dentro de la vista de desplazamiento
Agregue las restricciones superior, izquierda, derecha, inferior, centro X y centro Y desde la vista de desplazamiento y la vista de pila a sus súper vistas relevantes
Asegúrese de que las restricciones estén vinculadas desde la vista de pila a la supervista correcta (vista de desplazamiento) ya que la configuración predeterminada actual es agregar una restricción Alinear superior y no una de Espacio superior.
fuente