Digamos que he agregado más vistas en UIStackView que se pueden mostrar, ¿cómo puedo hacer el UIStackView
desplazamiento?
ios
uiscrollview
uistackview
itsaboutcode
fuente
fuente
Respuestas:
En caso de que alguien esté buscando una solución sin código , creé un ejemplo para hacerlo completamente en el guión gráfico, usando el diseño automático.
Puedes obtenerlo de github .
Básicamente, para recrear el ejemplo (para desplazamiento vertical):
UIScrollView
y establezca sus restricciones.UIStackView
aUIScrollView
Leading
,Trailing
,Top
yBottom
debe ser igual a los deUIScrollView
Width
restricción igual entreUIStackView
yUIScrollView
.UIStackView
UIViews
laUIStackView
Intercambie
Width
porHeight
en el paso 4, y establezcaAxis
=Horizontal
en el paso 5, para obtener un UIStackView horizontal.fuente
La Guía de diseño automático de Apple incluye una sección completa sobre Trabajar con vistas de desplazamiento . Algunos fragmentos relevantes:
Además:
Para resumir, la vista de contenido de la vista de desplazamiento (en este caso, una vista de pila) debe estar anclada a sus bordes y su ancho y / o altura deben estar restringidos. Eso significa que el contenido de la vista de la pila debe estar restringido (directa o indirectamente) en la dirección o direcciones en las que se desea el desplazamiento, lo que podría significar agregar una restricción de altura a cada vista dentro de una vista de la pila de desplazamiento vertical, por ejemplo. El siguiente es un ejemplo de cómo permitir el desplazamiento vertical de una vista de desplazamiento que contiene una vista de pila:
fuente
Need constraints for: Y position or height.
este error solo desaparece si establece una restricción de ancho y altura para la vista de la pila, que deshabilita el desplazamiento vertical. ¿Este código todavía funciona para ti?Las restricciones en la respuesta mejor votada aquí funcionaron para mí, y he pegado una imagen de las restricciones a continuación, tal como se creó en mi guión gráfico.
Sin embargo, encontré dos problemas que otros deberían tener en cuenta:
Después de agregar restricciones similares a las que figuran en la respuesta aceptada, obtendría el error rojo de auto-distribución
Need constraints for: X position or width
. Esto se resolvió agregando un UILabel como una subvista de la vista de pila.Estoy agregando las subvistas programáticamente, por lo que originalmente no tenía subvistas en el guión gráfico. Para deshacerse de los errores de distribución automática, agregue una subvista al guión gráfico, luego quítelo en carga antes de agregar sus subvistas y restricciones reales.
Originalmente intenté agregar
UIButtons
a UIStackView. Los botones y las vistas se cargarían, pero la vista de desplazamiento no se desplazaría . Esto se resolvió agregandoUILabels
a la Vista de pila en lugar de botones. Usando las mismas restricciones, esta jerarquía de vistas con UILabels se desplaza pero UIButtons no.Estoy confundido por este problema, ya que los UIButtons no parecen tener un IntrinsicContentSize (utilizado por la pila Vista). Si alguien sabe por qué los botones no funcionan, me encantaría saber por qué.
Aquí está mi jerarquía de vista y restricciones, para referencia:
fuente
Como dice Eik,
UIStackView
yUIScrollView
juegan juntos muy bien, mira aquí .La clave es que
UIStackView
maneja la altura / ancho variable para diferentes contenidos yUIScrollView
luego hace bien su trabajo de desplazamiento / rebote de ese contenido:fuente
Estaba buscando hacer lo mismo y me topé con esta excelente publicación. Si desea hacer esto mediante programación utilizando la API de anclaje, este es el camino a seguir.
Para resumir, incrusta tu
UIStackView
en tuUIScrollView
y establece las restricciones de anclaje de laUIStackView
para que coincidan con las de laUIScrollView
:fuente
Al día para 2020.
100% storyboard O 100% código.
Aquí está la explicación más simple posible:
Tener una escena en pantalla completa en blanco
Agregar una vista de desplazamiento. Control-arrastre desde la vista de desplazamiento a la vista base , agregue izquierda-derecha-arriba-abajo, todo cero.
Agregue una vista de pila en la vista de desplazamiento. Control-arrastre desde la vista de pila a la vista de desplazamiento , agregue izquierda-derecha-arriba-abajo, todo cero.
Ponga dos o tres etiquetas dentro de la vista de pila.
Para mayor claridad, haga que el color de fondo de la etiqueta sea rojo. Establezca la altura de la etiqueta en 100.
Ahora configure el ancho de cada UILabel:
Sorprendentemente, arrastre el control de la
UILabel
vista de desplazamiento a la vista de desplazamiento, no a la vista de pila, y seleccione anchos iguales .Repetir:
No controle el arrastre del UILabel al padre del UILabel: vaya al abuelo. (En otras palabras, vaya hasta la vista de desplazamiento, no vaya a la vista de pila).
Es así de simple. Ese es el secreto
Ya terminaste
Consejo: debe agregar una altura a cada elemento nuevo . Cada elemento en cualquier vista de pila de desplazamiento debe tener un tamaño intrínseco (como una etiqueta) o agregar una restricción de altura explícita.
El enfoque alternativo:
En lo anterior: sorprendentemente, establezca los anchos de las UILabels al ancho de la vista de desplazamiento (no la vista de la pila).
Alternativamente...
Arrastre desde la vista de pila a la vista de desplazamiento y agregue una restricción de "ancho igual". Esto parece extraño porque ya lo anclaste de izquierda a derecha , pero así es como lo haces . No importa cuán extraño parezca, ese es el secreto.
Así que tienes dos opciones:
o
Para ser claros, haga UNO de esos métodos, NO haga los dos.
fuente
Desplazamiento horizontal (UIStackView dentro de UIScrollView)
Para desplazamiento horizontal. Primero, cree ay
UIStackView
aUIScrollView
y agréguelos a su vista de la siguiente manera:Recordando a establecer la
translatesAutoresizingMaskIntoConstraints
afalse
en elUIStackView
y elUIScrollView
:Para que todo funcione, los anclajes posteriores, superiores e inferiores
UIStackView
deben ser iguales a losUIScrollView
anclajes:Pero el ancho del anclaje
UIStackView
debe ser igual o mayor que el ancho delUIScrollView
anclaje:Ahora ancla tu
UIScrollView
, por ejemplo:A continuación, sugeriría probar las siguientes configuraciones para la
UIStackView
alineación y distribución:Finalmente, deberá usar el
addArrangedSubview:
método para agregar subvistas a su UIStackView.Inserciones de texto
Una característica adicional que puede resultarle útil es que, dado que se
UIStackView
encuentra dentro de unaUIScrollView
, ahora tiene acceso a inserciones de texto para que las cosas se vean un poco más bonitas.fuente
Solo agregue esto a
viewdidload
:fuente: https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/LayoutUsingStackViews.html
fuente
Puede probar ScrollableStackView : https://github.com/gurhub/ScrollableStackView
Es una biblioteca compatible con Objective-C y Swift. Está disponible a través de CocoaPods .
Código de muestra (Swift)
Código de muestra (Objetivo-C)
fuente
Si tiene una restricción para centrar la Vista de pila verticalmente dentro de la vista de desplazamiento, simplemente quítela.
fuente
Ejemplo para una vista vertical de pila / vista de desplazamiento (usando
EasyPeasy
para autolayout):¡Solo asegúrese de que cada una de las alturas de su subvista esté definida!
fuente
En primer lugar, diseñe su vista, preferiblemente en algo como Sketch u obtenga una idea de lo que desea como contenido desplazable.
Después de esto, haga que el controlador de vista tenga forma libre (elija del inspector de atributos) y establezca la altura y el ancho según el tamaño del contenido intrínseco de su vista (a elegir del inspector de tamaño).
Después de esto, en el controlador de vista, coloque una vista de desplazamiento y esta es una lógica, que he encontrado que funciona casi todas las veces en iOS (puede requerir revisar la documentación de esa clase de vista que se puede obtener mediante comando + clic en esa clase o en google)
Si está trabajando con dos o más vistas, primero comience con una vista que se haya introducido anteriormente o sea más primitiva y luego vaya a la vista que se introdujo más tarde o que es más moderna. Entonces, como la vista de desplazamiento se introdujo primero, comience con la vista de desplazamiento primero y luego vaya a la vista de pila. Aquí ponga las restricciones de la vista de desplazamiento a cero en todas las direcciones con respecto a su super vista. Coloque todas sus vistas dentro de esta vista de desplazamiento y luego póngalas en la vista de pila.
Mientras trabaja con la vista de pila
Primero comience con ground up (enfoque de abajo hacia arriba), es decir, si tiene etiquetas, campos de texto e imágenes en su vista, luego presente estas vistas primero (dentro de la vista de desplazamiento) y luego póngalas en la vista de pila.
Después de eso, modifique la propiedad de la vista de pila. Si aún no se logra la vista deseada, utilice otra vista de pila.
Después de hacer su vista, coloque una restricción entre la vista de la pila madre y la vista de desplazamiento, mientras que la vista de la pila secundaria de los niños con la vista de la pila madre. Con suerte, para este momento debería funcionar bien o puede recibir una advertencia de Xcode dando sugerencias, lea lo que dice e implemente esas. Con suerte, ahora debería tener una visión funcional según sus expectativas :).
fuente
Para la vista de pila apilada o anidada, la vista de desplazamiento debe tener un ancho fijo con la vista raíz. La vista de la pila principal que está dentro de la vista de desplazamiento debe establecer el mismo ancho. [Mi vista de desplazamiento está debajo de una vista ignorarlo]
fuente
Si alguien busca una vista de desplazamiento horizontal
fuente
Coloque una vista de desplazamiento en su escena y modifíquela para que llene la escena. Luego, coloque una vista de pila dentro de la vista de desplazamiento y coloque el botón Agregar elemento dentro de la vista de pila. Tan pronto como todo esté en su lugar, establezca las siguientes restricciones:
código:
Stack View.Width = Scroll View.Width
es la clave.fuente
Agregar una nueva perspectiva para macOS Catalyst. Dado que las aplicaciones macOS admiten el cambio de tamaño de la ventana, es posible que su
UIStackView
transición de un estado no desplazable a uno desplazable, o viceversa. Aquí hay dos cosas sutiles:UIStackView
está diseñado para adaptarse a todas las áreas que puede.UIScrollView
intentará cambiar el tamaño de sus límites para tener en cuenta el área recién adquirida / perdida debajo de su barra de navegación (o barra de herramientas en el caso de las aplicaciones de macOS).Desafortunadamente, esto creará un bucle infinito. No estoy muy familiarizado con
UIScrollView
su yadjustedContentInset
, pero desde mi inicio de sesión en sulayoutSubviews
método, veo el siguiente comportamiento:UIScrollView
intenta reducir sus límites (ya que no es necesario el área debajo de la barra de herramientas).UIStackView
sigue.UIScrollView
no está satisfecho, y decide restaurar a los límites más grandes. Esto me parece muy extraño ya que lo que veo en el registro es esoUIScrollView.bounds.height == UIStackView.bounds.height
.UIStackView
sigue.Me parece que dos pasos solucionarían el problema:
UIStackView.top
aUIScrollView.topMargin
.contentInsetAdjustmentBehavior
a.never
.Aquí me preocupa una vista desplazable verticalmente con un crecimiento vertical
UIStackView
. Para un par horizontal, cambie el código en consecuencia.Espero que ayude a cualquiera en el futuro. No pude encontrar a nadie que mencionara esto en Internet y me costó mucho tiempo descubrir qué sucedió.
fuente