Cómo usar UIScrollView en Storyboard

125

Tengo una vista de desplazamiento con contenido de 1000 px de altura y me gustaría poder diseñarlo para un diseño fácil en el guión gráfico.
Sé que se puede hacer mediante programación, pero realmente quiero poder verlo visualmente. Cada vez que coloco una vista de desplazamiento en un controlador de vista, no se desplazará. ¿Es posible que funcione como quiero o tengo que hacerlo en el código?

Alex Reynolds
fuente
1
Hola a todos, vea los comentarios a continuación para conocer nuevas formas de hacerlo Escribí esto hace 2 años y xCode ha cambiado mucho. Hay otras formas de hacer esto ahora, así que tenga en cuenta. Soluciones iOS 7 e iOS 8 sugeridas en los comentarios
Alex Reynolds
Aquí estoy otra vez, 2 años después, todavía recibo comentarios sobre cómo esto no funciona o si la autolaminación es mejor. La pregunta original era cómo hacerlo en iOS 5/6. Solo uso autolayout en estos días para esto, así que tú también deberías / puedes hacerlo. Consulte las respuestas sobre autolayout para obtener ayuda. Vota a favor las respuestas de autoejecución si son útiles. Gracias a todos
Alex Reynolds

Respuestas:

149

Estoy respondiendo mi propia pregunta porque acabo de pasar 2 horas para encontrar la solución y StackOverflow permite este estilo de control de calidad.

Comience a terminar aquí es cómo hacerlo funcionar en el guión gráfico.

1: vaya a su controlador de vista y haga clic en Attribute Inspector.

2: cambie el Tamaño a en Freeformlugar de Inferido.

3: Vaya a la vista principal en ese guión gráfico, no a su vista de desplazamiento, sino a la vista de nivel superior.

4: haga clic Size Inspectory establezca esta vista en el tamaño deseado. Cambié mi estatura a 1000.

Ahora verá que su guión gráfico tiene su configuración de vista para que pueda ver la altura completa de su desplazamiento para un diseño fácil.

5: Coloque una vista de desplazamiento y estírela para que ocupe toda la vista. Ahora debería tener una vista de desplazamiento con un tamaño de 320,1000 sentado en una vista en su controlador de vista.

Ahora necesitamos hacer que se desplace y que muestre el contenido correctamente.

6: Haga clic en su vista de desplazamiento y haga clic en Identity Inspector.

7: Agregue un User Defined runtime attributecon KeyPath del contentSizetipo de TAMAÑO y coloque el tamaño de su contenido. Para mí es (320, 1000).

Como queremos ver toda nuestra vista de desplazamiento en el guión gráfico, lo estiramos y tiene un marco de 320,1000, pero para que esto funcione en nuestra aplicación, necesitamos cambiar el marco a lo que será la vista de desplazamiento visible.

8: Agregar un runtime attributecon KeyPathframe con Tipo RECT y 0,0,320,416.

Ahora, cuando ejecutamos nuestra aplicación, tendremos una vista de desplazamiento visible que tiene un marco de 0,0,320, 416 y puede desplazarse hacia abajo hasta 1000. Podemos diseñar nuestras subvistas e imágenes y otras cosas en Storyboard tal como queremos que aparezcan. Luego, nuestros atributos de tiempo de ejecución se aseguran de mostrarlo correctamente. Todo esto sin 1 línea de código.

Alex Reynolds
fuente
55
Si utiliza correctamente la función de cambio automático de tamaño de vista de desplazamiento, no necesita definir el frameatributo. De hecho, todos los dispositivos no tienen exactamente el mismo tamaño (iPhone 5).
Tronix117
Tronix117, entonces, ¿cómo resuelves este problema sin ese atributo?
Andras Hatvani
2
Si tiene una solución para iOS 7, avíseme. Esta respuesta fue publicada hace más de un año antes de iOS 7. Estoy abrumado o actualizaría esto para iPhone5 y ios7
Alex Reynolds
2
NOTA: La solución para iOS 7 se encuentra debajo de stackoverflow.com/a/22489795/1553014
Raja Rao
1
Nota: Para iOS 8.3 XCode 6.3, la respuesta está aquí: stackoverflow.com/questions/26742230/…
T.Coutlakis
51

Estos son los pasos con los Auto Layoutque funcionó para mí en XCode 8.2.1.

  1. Seleccionar Size Inspectorde View Controller, y cambiar Simulated Sizea Freeformla altura de 1000 en lugar deFixed .
  2. Cambie el nombre de la vista View Controllercomo RootView .
  3. Arrastre una vista secundariaScroll View de RootView y cámbiele el nombre a ScrollView .
  4. Agregar restricciones para ScrollView :
    • ScrollView [Superior, Inferior, Principal, Final] = RootView [Top, Bottom, Leading, Trailing]
  5. Arrastre una Vertical Stack Viewcomo subvista de ScrollView y nombre por ContentView .
  6. Agregar restricciones para ContentView :
    • ContentView .height = 1000
    • ContentView [Superior, Inferior, Principal, Final, Ancho] = ScrollView [Superior, Inferior, Principal, Final, Ancho]
  7. Seleccione Attributes Inspectorde ContentView , y cambiar Distributionde Fill Equallylugar de Fill.
  8. Arrastre una Viewsubvista como ContentView y cámbiele el nombre a RedView .
  9. Establecer Redcomo fondo de RedView .
  10. Arrastre una Viewsubvista como ContentView y cámbiele el nombre a BlueView .
  11. Establecer Bluecomo fondo de BlueView .
  12. Seleccione RootView y haga clic en el Update Framesbotón.
    • Update Frameses un nuevo botón en Xcode8, en lugar de Resolve Auto Layout Issuesbotón. Parece un botón de actualización, ubicado en la barra de control debajo del Guión gráfico: Botón Actualizar marcos

Ver jerarquía:

  • RootView
    • ScrollView
      • ContentView
        • RedView
        • BlueView

Ver escena del controlador (Altura: 1000):

escena

Ejecutar en iPhone7 (Altura: 1334/2):

manifestación

jqgsninimo
fuente
Tengo el mismo problema y me pregunto si esto funcionaría cuando mi scrollview no sea del tamaño de rootview.
GalaxyVintage
Pero la cosa es que tendrá un espacio en blanco en la parte inferior para el ipad
G.Abhisek
Una nota para configurar BlueViewde arriba a RedViewabajo para principiantes como yo (Xcode 8.2): 1) Arrastre el BlueView siguiente RedView (es decir, no deben superponerse o el paso 4) no funcionará). 2) Abra el menú pin en la parte inferior. 3) Haga clic en la flecha pequeña a la derecha de la restricción del margen superior. 4) Seleccione RedViewde ese menú y establezca el valor en 0. Esto es diferente de las versiones anteriores de Xcode donde podría hacer cosas como Editor-> Pin-> ...
Krøllebølle
Por curiosidad, ¿por qué utiliza una vista de pila vertical en lugar de una vista general de UIView?
Cambiadores
@Changerrs que uso UIStackViewpara evitar el problema de establecer restricciones.
jqgsninimo
43

Estos son los pasos que me funcionaron en iOS 7 y XCode 5.

  1. Arrastre un ViewController (viene con UIView "View").

    1.1 Seleccione "Ver controlador" y seleccione "Inspector de archivos" y desmarque "Diseño automático".

  2. Arrastre una Vista de desplazamiento (como elemento secundario de la "Vista" de UIView de ViewController)
  3. Seleccione ScrollView y abra "Identity Inspector".
  4. Ingrese "contentSize" para keyPath. Seleccione "Tamaño" para Tipo. Y entre {320, 1000} para el valor.

    Nota: El paso 4 simplemente dice que el desplazador contiene contenido cuyo tamaño es de 320x1000 unidades. Por lo tanto, configurar contentSize hará que el desplazamiento funcione.

  5. Seleccione Ver controlador, seleccione "Inspector de atributos" y luego seleccione Forma libre en Tamaño.

    Nota: el paso 5 nos permitirá cambiar el tamaño de "Vista" que viene con el controlador de vista.

  6. Seleccione "Ver" y luego seleccione "Inspector de tamaño".

  7. Establezca Ancho a 320 y alto a 1000.

Nota: 5, 6 y 7 es puramente para nosotros ver una vista ampliada o completa dentro de StoryBoard. Nota: Asegúrese de anular la selección de "Diseño automático" en View Controller.

Su jerarquía de vistas debería verse así: jerarquía

Raja Rao
fuente
3
Esta técnica todavía funciona a partir de Xcode 6.1 y iOS 8.1.
Chris Harris
1
Asombroso. Gracias por esto. Definitivamente funciona en Xcode 6.1 y iOS 8.1 como se mencionó.
Shanker Kaura
45
Ok ... ¿qué pasa si NECESITAMOS autolayout?
PostCodeism
1
Mutch mejor respuesta .. Gracias!
StefMa
1
Solución para iOS 8 Diseño automático y clase de tamaño stackoverflow.com/questions/26742230/…
jithin
13

Después de horas de prueba y error, he encontrado una manera muy fácil de poner contenido en vistas de desplazamiento que están 'fuera de pantalla'. Probado con XCode 5 e iOS 7. Puede hacerlo casi por completo en Storyboard, utilizando 2 pequeños trucos / soluciones:

  1. Arrastre un controlador de vista a su guión gráfico.
  2. Arrastre un scrollView en este viewController, para la demostración puede dejar su tamaño predeterminado, cubriendo toda la pantalla.
  3. Ahora viene el truco 1 : antes de agregar cualquier elemento a scrollView, arrastre en una 'vista' normal (esta vista se hará más grande que la pantalla y contendrá todos los subelementos como botones, etiquetas, ... llamémosle el ' vista de cierre ').
  4. Deje que el tamaño Y de esta vista envolvente en el inspector de tamaño sea, por ejemplo, 800.
  5. Coloque una etiqueta en la vista adjunta, en algún lugar de la posición Y 200, asígnele el nombre 'etiqueta 1'.
  6. Truco 2 : asegúrese de que esté seleccionada la vista adjuntano la vista de desplazamiento! ) Y configure su posición Y en, por ejemplo, -250, para que pueda agregar un elemento que esté 'fuera' de la pantalla
  7. Coloque una etiqueta, en algún lugar en la parte inferior de la pantalla, asígnele el nombre 'etiqueta 2'. Esta etiqueta es en realidad "fuera de pantalla".
  8. Restablezca la posición Y de la vista adjunta a 0, ya no verá la etiqueta 2, ya que se colocó fuera de la pantalla.

Hasta ahora para el trabajo del guión gráfico, ahora necesita agregar una sola línea de código al método 'viewDidLoad' de viewController para establecer el contenido de scrollViews para que contenga toda la 'vista de cierre'. No encontré una manera de hacer esto en Storyboard:

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.scrollView.contentSize = CGSizeMake(320, 800);
}

Puede intentar hacer esto agregando un contentSizekeyPath comosize a al scrollView en el Inspector de identidad y configurándolo en (320, 1000).

Creo que Apple debería hacer esto más fácil en storyboard, en un TableViewController puede simplemente desplazarse fuera de la pantalla en Storyboard (solo agregue 20 celdas, y verá que simplemente puede desplazarse), esto también debería ser posible con un ScrollViewController.

Ronny Webers
fuente
1
eso es correcto jaxvy, cuando recientemente exporté mi aplicación para admitir el diseño automático, he reemplazado la vista de desplazamiento con una vista de tabla estática. Hace el mismo trabajo y tiene algunas ventajas adicionales también.
Ronny Webers
¿Qué pasa con el cambio de contenido? Tamaño dinámicamente porque todos los iPhones vienen con diferentes tamaños
veeresh kumbar
8

Hacer que Scrolling funcione en iOS7 y Auto-layout en iOS 7 y XCode 5.

Además de esto: https://stackoverflow.com/a/22489795/1553014

Aparentemente, todo lo que necesitamos hacer es:

  1. Establezca todas las restricciones en la Vista de desplazamiento (es decir, primero corrija la vista de desplazamiento)

  2. Luego establezca la restricción distance-from-scrollView en el elemento más inferior para ver la vista de desplazamiento (que es la supervista).

Nota: El paso 2 le dirá al guión gráfico dónde se encuentra el último contenido dentro de la vista de desplazamiento.

Raja Rao
fuente
7

Para este ejemplo, desmarqué la función Autolayout del generador de interfaces. Y sigo usando (sin ningún motivo) la versión 4.6.1 relativamente antigua de Xcode.

Comience con un controlador de vista que tenga una vista de desplazamiento sobre él (la vista principal).

1: Agregue una vista de contenedor, desde la biblioteca de objetos, a la vista de desplazamiento. Observe que se agrega un nuevo controlador de vista al guión gráfico y se vincula al controlador de vista con la vista de desplazamiento.

2: Seleccione la vista de contenedor y, en el Inspector de tamaño, fíjela a la parte superior e izquierda sin cambiar el tamaño automáticamente.

ingrese la descripción de la imagen aquí

3: Cambie su altura a 1000. (1000 se usa para este ejemplo. Debe aplicar el valor que necesita).

4: Seleccione el nuevo controlador de vista y, desde el Inspector de atributos, cambie el Tamaño a Forma libre.

ingrese la descripción de la imagen aquí

5: Seleccione la vista del nuevo controlador de vista y, en el tamaño Inspector, cambie la altura a 1000 (que es igual a la altura de la vista del contenedor).

6: Para su prueba posterior, mientras todavía está en la vista del nuevo controlador de vista, agregue una etiqueta en la parte superior e inferior de la vista.

7: Seleccione la vista de desplazamiento desde el controlador de vista original. En el inspector de identidad, agregue un atributo con keyPath establecido en contentSize, escriba set en Size y value set en {320, 1000} (o el tamaño de la vista del contenedor).

ingrese la descripción de la imagen aquí

8: Ejecutar en el simulador de iPhone de 4 pulgadas. Debería poder desplazarse desde la etiqueta superior hasta la etiqueta inferior.

9: Ejecutar en el simulador de iPhone de 3.5 pulgadas. Debería poder desplazarse desde la etiqueta superior hasta la etiqueta inferior.

Recuerde que Xcode 4.6.1 solo puede compilarse para iOS6 y versiones inferiores. Usando este enfoque y compilando para iOS6, todavía puedo lograr los mismos resultados cuando la aplicación se ejecuta en iOS7.

yoninja
fuente
5

Tenga en cuenta que dentro de a UITableView, puede desplazar la vista de tabla seleccionando una celda o un elemento en ella y desplazándose hacia arriba o hacia abajo con su panel táctil.

Por un lado UIScrollView, me gusta la sugerencia de Alex, pero recomendaría cambiar temporalmente el controlador de vista a forma libre, aumentar la altura de la vista raíz, construir su interfaz de usuario (pasos 1-5) y luego volver a cambiarla al tamaño inferido estándar cuando haya terminado para que no tenga que codificar los tamaños de contenido como atributos de tiempo de ejecución. Si lo hace, se está abriendo a una gran cantidad de problemas de mantenimiento que intentan admitir dispositivos de 3.5 "y 4", así como la posibilidad de mayores resoluciones de pantalla en el futuro.

Kyle Clegg
fuente
4

Solo debe establecer la propiedad contentSize en viewDidAppear, como este ejemplo:

- (void)viewDidAppear:(BOOL)animated{

     [super viewDidAppear:animated];
     self.scrollView.contentSize=CGSizeMake(306,400.0);

}

Resuelve los problemas de autolayout y funciona bien en iOS7.

Lucio Fonseca
fuente
NOTA: Alex Zavatone ofrece una forma alternativa de configurar contentSize, sin escribir código.
ToolmakerSteve
4

Descargo de responsabilidad: - Solo para ios 9 y superior (vista de pila).

Si está implementando su aplicación en dispositivos ios 9, use una vista de pila . Aquí están los pasos: -

  1. Agregue una vista de desplazamiento con restricciones: anclar a la izquierda, derecha, abajo, arriba (sin márgenes) a la supervista (vista)
  2. Agregue una vista de pila con las mismas restricciones a la vista de desplazamiento.
  3. Vista de pila Otras restricciones: - stackView.bottom = view.bottom y stackView.width = scrollView.width
  4. Comience a agregar sus puntos de vista. La vista de desplazamiento decidirá desplazarse según el tamaño de la vista de pila (que es esencialmente su vista de contenido)
DharinS
fuente
1
Esta es una técnica útil que minimiza la cantidad de restricciones que tiene que agregar manualmente. En general, la forma de obtener el desplazamiento es asegurarse de que haya restricciones suficientes para que la distribución automática calcule el tamaño del contenido. La vista de pila hace mucho de eso para ti. Establezca la pila spacingpara poner algo de espacio entre las subvistas (elementos secundarios). Si necesita más espacio entre solo dos subvistas, agregue un elemento secundario "espaciador": una vista UIV transparente con tamaño fijo.
ToolmakerSteve
4

En iOS7 descubrí que si tuviera una Vista dentro de un UIScrollView en un ViewController de tamaño FreeForm, no se desplazaría en la aplicación, sin importar lo que hiciera. Jugué y encontré que lo siguiente parecía funcionar, que no usa FreeForms:

  1. Inserte un UIScrollView dentro de la Vista principal de un ViewController

  2. Establezca las restricciones de Autolayout en ScrollView según corresponda. Para mí, utilicé 0 para la guía de diseño superior y 0 para la guía de diseño inferior

  3. Dentro de la Vista de desplazamiento, coloque una Vista de contenedor. Establezca su altura a lo que quiera (por ejemplo, 1000)

  4. Agregue una restricción de Altura (1000) al Contenedor para que no cambie su tamaño. La parte inferior pasará el final del formulario.

  5. Agregue la línea [self.scrollView setContentSize: CGSizeMake (320, 1000)]; al ViewController que contiene scrollView (que ha conectado como IBOutlet)

El ViewController (agregado automáticamente) que está asociado con el Contenedor tendrá la altura deseada (1000) en Interface Builder y también se desplazará correctamente en el controlador de vista original. Ahora puede usar el ViewController del contenedor para diseñar sus controles.

nh32rg
fuente
He votado esta respuesta porque me gusta la técnica; Sin embargo, creo que está equivocado acerca de que FreeForm VC interfiere con el desplazamiento, independientemente de la versión de iOS. A partir de iOS 6 (que agregó el diseño automático), se desplazará un conjunto completo de restricciones, como se documenta en otras respuestas . No creo que FreeForm interfiera con eso (aunque no lo he probado). Quizás te estabas perdiendo alguna restricción no obvia; ScrollView + AutoLayout es un poco hack.
ToolmakerSteve
3

Quiero poner mis 5 centavos a la respuesta aceptada: he estado investigando el tema durante 2 días y finalmente encontré una solución que usaré siempre de ahora en adelante

vaya al elemento 4 en la respuesta aceptada y olvide agregar atributos de marcos y tamaños de contenido, etc.

para hacer que todo sea automático solo use la solución de este enlace

todo es claro, fácil, elegante y funciona como un encanto en iOS 7. Estoy bastante contento con todo eso jajaja

selva_mole
fuente
enlace actualizado
ToolmakerSteve
su solución (si sigue su enlace hasta el final) implica agregar una línea de código, por lo que esto no está particularmente en línea con la pregunta, usando solo el guión gráfico
Boris Gafurov
@BorisGafurov no está un poco desactualizado con ios7 de todos modos. y mb no está en línea, pero estoy seguro de que ha ayudado a un par de personas de todos modos ... así que déjalo estar
jungle_mole
3

Aquí hay una solución simple.

  1. Establezca el atributo de tamaño de su controlador de vista en el guión gráfico en "Forma libre" y establezca el tamaño que desee. Asegúrese de que sea lo suficientemente grande como para ajustarse al contenido completo de su vista de desplazamiento.

  2. Agregue su vista de desplazamiento y establezca las restricciones como lo haría normalmente. es decir, si desea que la vista de desplazamiento sea del tamaño de su vista, adjunte los márgenes superior, inferior, inicial y posterior a la supervista como lo haría normalmente.

  3. Ahora solo asegúrese de que haya restricciones en las subvistas de la vista de desplazamiento que conectan la parte superior e inferior de la vista de desplazamiento. Lo mismo para izquierda y derecha si tiene desplazamiento horizontal.

ingrese la descripción de la imagen aquí

Hulk Smash
fuente
2

Aquí hay una respuesta un poco sucia que llega a la misma solución para las vistas de desplazamiento vertical, pero (en contra del espíritu del stackoverflow) no responde la pregunta. En lugar de usar un scrollView, solo use un UITableView, arrastre un UIView normal al encabezado y hágalo tan grande como desee, ahora puede desplazar el contenido en el guión gráfico.

TimWhiting
fuente
En mi humilde opinión, es una buena respuesta, no en contra del espíritu de stackoverflow, sugerir un enfoque alternativo (a menos que OP específicamente diga que necesitan hacerlo de la forma en que preguntan). Y el mayor valor de stackoverflow es ayudar a todas las demás personas que vienen y lea las preguntas y respuestas. :)
ToolmakerSteve
0

¡Aparentemente no necesitas especificar la altura en absoluto! Lo cual es genial si cambia por alguna razón (cambia el tamaño de los componentes o cambia el tamaño de fuente).

Acabo de seguir este tutorial y todo funcionó: http://natashatherobot.com/ios-autolayout-scrollview/

(Nota al margen: no es necesario implementar viewDidLayoutSubviews a menos que desee centrar la vista, por lo que la lista de pasos es aún más corta).

¡Espero que ayude!

Lukasz Czerwinski
fuente
0

La clave es el contentSize.

Esto a menudo falta y no se indica al agregar un UIScrollView.

Seleccione el UIScrollView y seleccione el Inspector de identidad.

Agregue un contentSizekeyPath comosize a al scrollView en el Inspector de identidad y configúrelo en (320, 1000).

Desplazarse lejos.

Alex Zavatone
fuente
Este es un enfoque, y lo he usado yo mismo. Sin embargo, no lo considero el enfoque preferido. Es "más limpio / más flexible" proporcionar un conjunto completo de restricciones, de modo que la distribución automática pueda calcular el tamaño del contenido. Tres alternativas: restricciones de arriba a abajo , o usar la vista de pila , o restringir a la posición del elemento inferior .
ToolmakerSteve
0

Si está utilizando el diseño automático, el mejor enfoque es utilizar UITableViewController con celdas estáticas en el guión gráfico.

También una vez enfrenté el problema con una vista que requiere mucho más desplazamiento, así que cambie el UIScrollView con la técnica mencionada anteriormente.

Usman Awan
fuente
0

Aquí se explica cómo configurar una vista de desplazamiento con Xcode 11

1 - Agregar vista de desplazamiento y establecer restricciones superiores, inferiores, iniciales y finales

ingrese la descripción de la imagen aquí

2 - Agregue una vista de contenido a la vista de desplazamiento, arrastre una conexión a la Guía de diseño de contenido y seleccione Principal, Superior, Inferior y Final. Asegúrese de establecer sus valores en 0 o las constantes que desee.

ingrese la descripción de la imagen aquí

3 - Arrastre desde la Vista de contenido a la Guía de diseño de cuadros y seleccione Anchos iguales

ingrese la descripción de la imagen aquí

4 - Establecer una constante de restricción de altura en la Vista de contenido

JP Aquino
fuente