Swift UIScrollView: implementación correcta para solo desplazamiento vertical

De antemano, pido disculpas porque diría que soy un principiante con la progtwigción de iOS.

Quiero usar UIScrollView porque el contenido que se muestra excede el alto de la pantalla. Por lo tanto, me gustaría solo un desplazamiento vertical y no un desplazamiento horizontal.

Estoy usando el Storyboard para dibujar las vistas con AutoLayout .

Aquí está la captura de pantalla de mi UIViewController con el UIScrollView :

introduzca la descripción de la imagen aquíintroduzca la descripción de la imagen aquí

Luego cambio la label a un gran text como ese

 override func viewDidLoad() { super.viewDidLoad() self.label1Label.text = "Seize jours après la chute du président Blaise Compaoré, le Burkina Faso a un nouveau chef d'EtatA l'issue d'ultimes tractions, civils et militairs se sont accordés, lundi 17 novembre, sur le nom du diplomate Michel KafandoSeize jours après la chute du président Blaise Compaoré, le Burkina Faso a un nouveau chef d'EtatA l'issue d'ultimes tractions, civils et militairs se sont accordés, lundi 17 novembre, sur le nom du diplomate Michel Kafando" self.label1Label.numberOfLines = 0 self.label1Label.sizeToFit() 

Mi problema es que si no establezco manualmente un ancho para mi ContentView (dentro de UIScrollView ), el desplazamiento es horizontal, no vertical. (Mira la Captura de pantalla a continuación):

introduzca la descripción de la imagen aquí

He intentado configurar contentSize como lo he visto en muchas publicaciones de Google, pero sin éxito:

 self.scrollView.contentSize = CGSizeMake(400.0, 600.0) 

Si configuro un ancho manualmente para mi contenido ( ie : 320pts ), el desplazamiento será vertical (BUENO), pero dependiendo del tamaño del iPhone, no cubrirá todo el ancho de la pantalla, como se muestra en la siguiente captura de pantalla:

introduzca la descripción de la imagen aquí

La pregunta es: ¿cuál es la implementación correcta para usar UIScrollView para tener una contentView que respete la restricción de autolayout ( full screen : 0top - 0bottom - 0left - 0right ) y que el desplazamiento sea solo vertical.

¡Muchas gracias por tu ayuda!

Mike Woelmer muestra cómo hacerlo correctamente con Interface Builder en el blog de objects atómicos.

http://spin.atomicobject.com/2014/03/05/uiscrollview-autolayout-ios/

También tengo mi propio código (sin implementación de storyboard) en github.

https://github.com/nadthevlad/AutolayotScrollview

No desea establecer la altura o el ancho de su contenido o vistas. En su lugar, desea utilizar pines y restricciones de Autocompletar para establecer cómo se comporta el scrollview.

  1. Cree su UIScrollView * scrollView.

  2. Desea crear una UIView * contentView en la que pondrá el rest de los elementos de su vista.

     [self.view addSubview:scrollView]; [scrollView addSubview:contentView]; [contentView addSubview:_label1]; [contentView addSubview:_label2]; [contentView addSubview:_label3]; [contentView addSubview:_label4]; [contentView addSubview:_label5]; [contentView addSubview:_label6]; 
  3. Pin los 4 bordes de scrollView a los 4 bordes de self.view

  4. Pin los bordes superior e inferior de contentView en la parte superior e inferior de scrollView.

  5. Esta es la parte difícil. Para establecer el tamaño horizontal, desea que los bordes anterior (derecho) y posterior (izquierdo) de la ContentView queden fijados a los bordes y al final de los bordes de la vista en lugar de scrollView. Aunque contenView es una vista secundaria de scrollView, sus restricciones horizontales llegarán fuera de scrollView y se conectarán a self.view.

  6. Pinea cualquier otro elemento de vista a contentView como lo harías normalmente.

El truco para permitir que UIScrollView se desplace en una sola dirección es hacer que el tamaño de contenido de UIScrollView para la dimensión restringida sea el mismo que el tamaño del marco de UIScrollView en la misma dimensión. Entonces, en este caso, scrollview.contentSize.width debería ser igual a scrollview.frame.size.width .

Con eso en mente, testing lo siguiente:

  1. Asegúrese de tener las restricciones configuradas de la misma manera que se describe en esta respuesta.

  2. Agregue el siguiente código a su controller de vista:

     override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews(); self.scrollView.contentSize.height = 3000; // Or whatever you want it to be. } 

Personalmente, realmente no soy un fanático de Auto Layout. Si está interesado en probar esto sin Auto Layout, es decir. solo con código en lugar de restricciones: puede desactivar el layout automático para la vista del controller de vista y cambiar el método viewWillLayoutSubviews para que se vea así:

 override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews(); self.scrollView.frame = self.view.bounds; // Instead of using auto layout self.scrollView.contentSize.height = 3000; // Or whatever you want it to be. } 

Esto es lo que siempre hago para desplazarme verticalmente del storyboard con restricciones:

1-arrastre un controller de vista

2-arrastre una vista de desplazamiento en la vista principal del controller con las restricciones L = 0, T = 0, T = 0 y B = 0 a su vista de supervisión (vista principal del controller).

3-arrastre un UIVIew en la vista de desplazamiento para que funcione como su vista de contenido con las restricciones L-0, T = 0, T = 0, B = 0 a su supervisión (la vista de desplazamiento)

  • así que aquí es el momento de configurar el tamaño de contenido de la vista de desplazamiento, que controla el desplazamiento horizontal y vertical de la siguiente manera.

4: para detener el desplazamiento horizontal, haga que la vista de contenido tenga el mismo ancho que la vista de desplazamiento con restricción.

5: la altura de la vista de contenido es igual a la altura de la vista del controller. Esto es temporal hasta que lo llenamos con contenido desplazable .

Controles de 6 elementos en la vista de contenido hasta el final.

7, y lo más importante, elimine la restricción que hizo en el punto 5 de la altura de la vista de contenido y, en lugar de hacerlo, haga que la restricción del control en la parte inferior de la vista de contenido tenga una alignment inferior. Esto ayuda a hacer que la vista de contenido se inicie desde el primer control de arriba hacia abajo hasta el último control (todo depende de este paso).

8-solo ejecute y los resultados deberían ser los esperados, de lo contrario, hágamelo saber.

¡Espero que esto ayude!

Utilizo esta implementación solo para scrollviews horizontales / verticales, aunque está en Objective-C, intentaré explicar la lógica si algo no está claro para ti.

 //Getting iDevice's screen width CGRect screenRect = [[UIScreen mainScreen] bounds]; CGFloat screenWidth = screenRect.size.width; //Setting the right content size - only height is being calculated depenging on content. CGSize contentSize = CGSizeMake(screenWidth, HEIGHT_OF_YOUR_CONTENT); self.scrollView.contentSize = contentSize; 

Ahora, el ancho de la propiedad contentSize de la scrollview se está uniendo al ancho real de la pantalla del dispositivo, por lo que la scrollview se desplazará solo en dirección vertical.

Gracias a @NadtheVlad, finalmente vi la luz. Un poco de violín adicional me enseñó que contentView solo debe estar fijado a Top, Bottom y Width de scrollView. No es necesario hacer reference a self.view.

Con EasyPeasy , esto es simplemente:

 scrollView <- Edges() contentView <- [Top(), Bottom(), Width().like(scrollView)]