ios - scrolling - uiscrollview swift programmatically




UIScrollView Tamaño del contenido desplazable Ambigüedad (16)

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.


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:

  1. scrollView con 0 restricciones a todos los bordes
  2. Botón centrado horizontal y vertical con restricciones de ancho y altura fijas
  3. Y, por supuesto, las advertencias molestas tienen un Has ambiguous scrollable content width y una Has 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.



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'.


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 -

  1. no tiene ningún tamaño de contenido intrínseco (por ejemplo, UIView )
  2. 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:

  1. 4 restricciones desde arriba, izquierda, abajo y derecha.

  2. 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


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.


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.


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


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:

  1. Dentro de UIScrollView agregue una UIView (podemos llamar a contentView );

  2. En este contentView , establezca los márgenes superior, inferior, izquierdo y derecho en 0 (por supuesto, desde el scrollView que es el superView ); 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.





interface-builder