ios - doesn - swift scrollview not scrolling
UIScrollView Tamaño del contenido desplazable Ambigüedad (24)
Solo debes asegurarte de que hay una manera de hacer una línea continua de restricciones desde la parte superior a la parte inferior de la vista de desplazamiento. [-XXX]
En mi caso, una vista de desplazamiento con desplazamiento horizontal, también necesitaba agregar restricciones de ancho y altura para cada elemento secundario de la vista de desplazamiento, aunque la nota técnica de Apple no lo dice.
Compañeros desarrolladores, 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 este 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 por cada lado (no hay problema). Luego agrego una restricción de espacio superior a la UILabel (no hay problema) (y puedo incluso fijar la altura / anchura de la etiqueta, no cambia nada, pero no es necesario debido al tamaño intrínseco de la etiqueta)
El problema comienza cuando agrego una restricción final a la UILabel:
Por ejemplo, el espacio final para: Superview es igual a: 25
Ahora se producen dos advertencias, y no entiendo por qué:
A) Ambigüedad del tamaño del contenido desplazable (la vista de desplazamiento tiene altura / anchura de contenido desplazable ambiguo)
B) Vistas mal ubicadas (Etiqueta esperada: x = -67 Real: x = 207
Hice este ejemplo mínimo en un proyecto nuevo que puede descargar y adjunté una captura de pantalla. Como puede ver, Interface Builder espera que la etiqueta se sitúe fuera del límite de UIScrollView (el rectángulo discontinuo de color naranja). La actualización del marco de la etiqueta con la herramienta Resolver problemas lo mueve justo allí.
Tenga en cuenta: si reemplaza el UIScrollView con una UIView, el comportamiento es el esperado (el marco de la etiqueta es correcto y de acuerdo con la restricción). Entonces 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 posicionada, exactamente donde se supone que debe estar y el UIScrollView se puede desplazar. Si HAGO actualizar 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 averiguar qué está pasando: https://github.com/Wirsing84/AutoLayoutProblem
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 punto, verá que una vista de contenido con desplazamiento tiene una advertencia ambigua sobre el tamaño del contenido, 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 de IB), y seleccionar "Falta Restricciones "opción.
A partir de ahora, cuando ejecute el proyecto, la vista de desplazamiento actualizará automáticamente el tamaño del contenido, sin necesidad de código adicional.
Creo que es un trabajo de 10 segundos a partir de ahora. Lo observé en XCode 7.3 e hice un video en él. Chequea aquí:
https://www.youtube.com/watch?v=yETZKqdaPiI
Todo lo que tienes que hacer, agrega una subvista a UIScrollView
con el mismo ancho y alto. Luego seleccione ViewController y presione Reset to suggested constraint
. Por favor revise el video para una comprensión clara.
Gracias
Echa 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 diseño automático. Ahora, lo único que todavía me deja desconcertado 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/
Es la respuesta para mi pregunta auto respondida 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:
- scrollView con 0 restricciones a todos los bordes
- Botón centrado horizontal y vertical con restricciones de ancho y altura fijas
- Y, por supuesto, las advertencias molestas tienen un
Has ambiguous scrollable content width
y unaHas ambiguous scrollable content height
.
Todo lo que tenemos que hacer es:
- Agregue 2 restricciones adicionales, por ejemplo, "0" para el final y / o espacio inferior para nuestra vista (vea el ejemplo en la captura de pantalla a continuación).
Importante: tienes que agregar restricciones finales y / o finales . No es "líder y superior" - ¡no es trabajo!
Puede comprobarlo en mi proyecto de ejemplo , que demuestra cómo solucionar este problema.
PD
Según la lógica, esta acción debe 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 establecida para estas restricciones de manera explícita). Estaré agradecido si alguien explica, por qué funciona en los comentarios a continuación.
Estaba recibiendo el mismo error .. he hecho siguiendo
- Vista (Superview)
- ScrollView 0,0,600,600
- Vista del interior de ScrollView: 0,0,600,600
- UIView contiene vista de imagen, etiqueta
Ahora agregue lead / trailing / top / bottom para scrollView (2) luego UIView (3).
La Vista (1) y la Vista (3) configuran la altura y el peso por igual ... resolvió mi problema.
He hecho el video que ayudará:
Establezca el tamaño del ViewController (el que contiene el UIScrollView) en Forma libre en el inspector de tamaño en Interface Builder y todo debería funcionar.
Este error me tomó un tiempo para localizarlo, 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 del ScrollView también se fijara en la parte inferior. De esa manera, 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 centradas en X en el ScrollView, pero también tenía que fijar los objetos al lado del ScrollView. No me gusta esto porque el iPhone6 podría tener una pantalla más ancha, pero eliminará el error ''ancho de contenido ambiguo''.
Finalmente me di cuenta de esto, espero que sea más fácil de entender.
Con frecuencia puede omitir esa advertencia agregando una vista UIV base a la vista de desplazamiento como una "vista de contenido", como mencionaron, y hacer que tenga el mismo tamaño que su vista de desplazamiento y, en esta vista de contenido, establezca estos 6 parámetros.
Como puedes ver, necesitas 6 parámetros totales! Que ... en circunstancias normales, estás duplicando 2 restricciones, pero esta es la forma de evitar este error del guión gráfico.
Hice un video en youTube
Desplácese desde StackViews utilizando solo Storyboard en Xcode
Creo que 2 tipos de escenarios pueden aparecer aquí.
La vista dentro del scrollView -
- no tiene ningún tamaño de contenido intrínseco (por ejemplo,
UIView
) - tiene su propio tamaño de contenido intrínseco (por ejemplo,
UIStackView
)
Para una vista de desplazamiento vertical en ambos casos, debe agregar estas restricciones:
4 restricciones desde arriba, izquierda, abajo y derecha.
Ancho igual a la vista de desplazamiento (para detener el desplazamiento horizontal)
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 del scrollView.
La respuesta de @Matteo Gobbi es perfecta, pero en mi caso, la vista de desplazamiento no puede desplazarse, elimino " alinear el centro Y " y agrego " altura> = 1 ", la vista de desplazamiento se convertirá en desplazable
Las personas que luchan con uiscrollview no se desplazan, simplemente establecen la restricción inferior de la vista de contenido con el diseño inferior de la última vista (que se encuentra dentro de la vista de contenido). No te olvides de quitar el centro de la restricción.
Resto todas las restricciones son las mismas que las definidas anteriormente. Scrollview 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 scrollview cambiará automáticamente su compensación de contenido.
En mi caso, la última vista fue UILable sin ninguna propiedad de líneas = 0 (que ajusta automáticamente su altura según su contenido), por lo que aumenta dinámicamente la altura de Uilable y, finalmente, nuestra área desplazable aumenta debido a que la disposición inferior de Uilable está alineada con la parte inferior de nuestra vista de contenido. lo que obliga a scrollview a aumentar su desplazamiento de contenido.
Lo que hice es 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 configuro el contentView de UIScrollView.
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 mejor me funcionó fue desactivar la comprobación de ambigüedad de mi scrollView
. Todo está muy bien, así que creo que está bien en casos simples como el mío. Pero tenga en cuenta que, si se rompen otras restricciones para su scrollView
, el Interface-Builder no le advertirá más al respecto.
Resolví este tipo de problema para mi vista usando "Resolver problemas de diseño automático"> "Agregar restricciones que faltan" para la Vista seleccionada
Las siguientes dos restricciones resuelven mi problema:
trailing = Stack View.trailing - 10
bottom = Stack View.bottom + 76
en el que: al final, abajo está el final, al final de UIScrollView
Sé que puedo llegar tarde, pero la siguiente solución resuelve este tipo de problemas sin código adicional , simplemente utilizando 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, establecer altura fija y centro x.
Espero que esto ayude.
Si alguien está experimentando un comportamiento en el que nota la barra de desplazamiento en los rollos de la derecha, pero el contenido no se mueve, probablemente vale la pena considerar este hecho:
También puede usar restricciones entre el contenido de la vista de desplazamiento y los objetos fuera de la vista de desplazamiento para proporcionar una posición fija para el contenido de la vista de desplazamiento, haciendo que el contenido aparezca flotando sobre la vista de desplazamiento.
Eso es de la documentation de Apple. Por ejemplo, si colocó accidentalmente su Etiqueta / Botón / Imagen / Vista superior en la vista fuera del área de desplazamiento (¿Quizás un encabezado o algo por encima de la Vista de desplazamiento?) En lugar de la Vista de contenido, congelaría toda la vista de contenido en su lugar.
Tuve el mismo problema y después de buscar en la documentación y no encontrar una solución aceptable. Debe crear una UIView como una subvista de UIScrollView como se describe a continuación:
- UIViewController
- UIView ''Vista principal''
- UIScrollView
- Vista de UIView ''Container View''
- [Tu contenido]
- Vista de UIView ''Container View''
- UIScrollView
El segundo paso es hacer las restricciones de UIScrollView. Hice esto con las restricciones superior, inferior, inicial y final de su superView.
A continuación, agregué las restricciones para el contenedor de UIScrollView y aquí es donde comienza el problema. Cuando pones las mismas restricciones (arriba, abajo, al principio y al final), el Guión gráfico muestra un mensaje de advertencia:
"Tiene un ancho de contenido desplazable ambiguo" y "Tiene una altura de contenido desplazable ambiguo"
Continúe con las mismas restricciones anteriores, y simplemente agregue las restricciones " Igualdad de altura " e " Igual ancho " a su Vista del contenedor en relación con la Vista principal y no a su UIScrollView. En otras palabras, las restricciones de la vista de contenedor están vinculadas a la vista de supervisión de UIScrollView.
Después de eso, no tendrá advertencias en su Guión gráfico y podrá continuar agregando las restricciones para sus subvistas.
Espero que esto ayude a alguien.
Usando contentView (UView) como contenedor dentro de UIScrollView, manténgase en los bordes (arriba, abajo, al final, adelante) de superview (UIScrollView) y contentView debe tener el mismo ancho y alto que la superview. Esas son las restricciones. Y llamada de método:
-(void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
self.scrollView.contentSize = self.contentView.frame.size;
}
Problemas resueltos para mi.
Vea a continuación: vista de contenido en scrollview vertical y horizontal centralizada. recibió un error de ambigüedad, asegúrese siempre de que dos agregados a la vista de desplazamiento desde su vista de contenido sean 1) .botón espacio a contenedor.2) espacio final a restricción que se resalta en la captura de pantalla,
esta restricción significa en el desplazamiento es cuánto puede desplazarse después de la altura o el ancho de su vista de contenido.
te puede ayudar
[probado en XCode 7.2 y para iOS 9.2]
Lo que suprimió los errores y advertencias del Guión gráfico 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) a Marcador de posición . 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 fijado todos los bordes de la vista de desplazamiento a la vista de supervisión y todos los bordes de la vista de pila a la vista de desplazamiento. En mi código, he establecido las translatesAutoresizingMaskIntoConstraints 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 loca y no quería centrar las cosas horizontal o verticalmente solo para suprimir la advertencia.
todas las subvistas dentro de una vista de desplazamiento deben tener restricciones que toquen todos los bordes de la vista de desplazamiento, como se explica en la documentación, la altura y el ancho de una vista de desplazamiento se calculan automáticamente por las medidas de las subvistas, esto significa que debe tener Restricciones iniciales y iniciales para el ancho y restricciones superiores e inferiores para la altura.
NOTA: En iOS> 10.0, esto no ha sido probado; por lo tanto, la solución podría ser incompleta en ciertas situaciones.
Así que acabo de resolver de esta manera:
Dentro de
UIScrollView
agregue unaUIView
(podemos llamar acontentView
);En este
contentView
, establezca los márgenes superior, inferior, izquierdo y derecho en 0 (por supuesto, desde elscrollView
que es elsuperView
); El conjunto también alinea el centro horizontalmente y verticalmente ;
Terminado
Ahora puede agregar todas sus vistas en esa vista de contentView
, y el contentSize
de contentSize
de la vista de scrollView
cambiará de tamaño automáticamente de acuerdo con la contentView
.
Actualizar:
Algunos casos especiales están cubiertos por este video publicado por @Sergio en los comentarios a continuación.
iOS 12, Swift 4
La forma más sencilla de usar autolayout:
- Agregue UIScrollView y ajústelo 0,0,0,0 para supervisar (o su tamaño deseado)
- Agregue UIView en ScrollView, ajústelo 0,0,0,0 a los 4 lados y céntrelo horizontalmente y verticalmente.
- En el inspector de tamaño, cambie la prioridad ''inferior'' y ''alinear el centro Y'' a 250. (para el cambio de desplazamiento horizontal ''arrastrando'' y ''alinear el centro X'')
- Agregue todas las vistas que necesite en esta vista. No te olvides de establecer la restricción inferior en la vista más baja.