¿Cómo uso UIScrollView en Interface Builder?

Aunque utilicé UIScrollView éxito en el pasado al manipularlo mediante progtwigción, tengo problemas para hacerlo funcionar configurándolo exclusivamente en Interface Builder.

Tengo una página “sobre” simple en mi aplicación de iPhone. Tiene una UITextView , algunos íconos y enlaces a mis otras aplicaciones. He agregado todas estas vistas a mi UIScrollView , organizándolas de modo que su tamaño total sea> 480. Cuando inicio mi aplicación, la vista de desplazamiento muestra solo los contenidos que se ajustan a la pantalla, y no se desplaza nada.

¿Es posible hacer esto completamente a través de IB, o debo manipular el tamaño del contenido a través del código?

Olvidó establecer la propiedad contentSize de UIScrollView. Curiosamente, no puedes hacer esto desde Interface Builder. Tendrás que hacerlo desde el controlador de vista que administra esta vista de desplazamiento.

La respuesta de Boby_Wan me hizo pensar, y encontré la siguiente solución para configurar el ContentSize de UIScrollView desde Interface Builder:

  1. Seleccione UIScrollView en la escena Storyboard
  2. Vaya al inspector de identidad , cree un nuevo atributo de tiempo de ejecución definido por el usuario (haga clic en el botón +)
  3. Cambiar el atributo Key Path to contentSize
  4. Cambiar el atributo Tipo a Size
  5. Ahora configure el valor en { ancho del contenido deseado, altura del contenido deseado }

por ejemplo, establecer el valor en {320, 920} permitirá al usuario desplazarse hacia abajo por una pantalla extra completa en el iPhone.

(Estoy usando xcode 4.3.3, el objective de implementación de iOS del proyecto es 5.1)

Cuando hice esto por primera vez, recibí el siguiente error:

Configuración ilegal:
Tipo de tamaño atributos de tiempo de ejecución definidos por el usuario con versiones Xcode anteriores a 4.3
MainStoryboard.storyboard

Si también obtiene este error, es fácil de arreglar: seleccione el Guión gráfico en el Navegador de proyectos y abra el Inspector de archivos . Busque / expanda la sección del Documento del Constructor de Interfaces , y hay un menú desplegable para Desarrollo . Asegúrese de que esté configurado en Xcode 4.3

Con Autolayout (iOS6 +), puede evitar configurar contentSize . Establezca las siguientes restricciones en su lugar:

  1. Fije la parte superior de la vista de desplazamiento a la parte superior de su primer hijo.
  2. Y fija la parte inferior en la parte inferior de su niño más inferior.

Puede hacerlo utilizando solo Interface Builder, vaya al Inspector de identidad (la tercera pestaña del inspector) y agregue un nuevo atributo de tiempo de ejecución definido por el usuario con

  • Ruta clave: contentSize
  • Tipo: Tamaño
  • Valor: {ancho, alto}

Ahora hay una manera de hacer un desplazamiento UIScrollView sin salir de Storyboard :

  1. Seleccione UIScrollView en Storyboard, vaya al inspector de tallas y cambie el valor Inferior (o cualquier otro valor que necesite cambiar) en la sección de Ingreso de contenido a la altura del área de contenido.
  2. Ahora vaya al inspector de identidad y cree un nuevo atributo de tiempo de ejecución definido por el usuario (haciendo clic en el botón +) y contentSize nombre contentSize . No importa qué tipo o valor completes (incluso puedes dejar su valor predeterminado).

Esto hará que UIScrollView funcione correctamente, aunque no sé por qué es necesario el segundo paso (me enteré por casualidad). 🙁

Un enfoque que he usado en el pasado es arrastrar la vista de desplazamiento fuera de su vista que contiene la vista en el constructor de interfaz, y establecer su tamaño real para lo que quiere que sea el tamaño de contenido.

Lo que no es intrínsecamente obvio sobre el constructor de interfaces es que puede tener vistas no asociadas que se almacenan en el plumín, pero que no son parte de la vista principal para la que el plumín está destinado principalmente.

en la vista en la que desea que la vista de desplazamiento en vivo, coloque un UIView simple, que use como marcador de posición. (Esto es simplemente para que pueda diseñar visualmente su ubicación. Si solo está utilizando toda la vista, puede omitir este paso y usar el segundo fragmento de código que proporciono al final de esta respuesta).

a continuación, puede completar la vista de desplazamiento con controles, exponiendo visualmente cómo quiere que sea. proporcione las propiedades de marcador de posición y de desplazamiento dentro de su controlador de vista para que pueda acceder a ellas en tiempo de ejecución.

en tiempo de ejecución, en – (void) viewDidLoad

 scrollView.contentSize = scrollView.frame.size; scrollView.frame = placeholder.frame; [placeholder.superview addSubView:scrollView]; [placeholder removeFromSuperview]; 

alternativamente (si no usó un marcador de posición):

 CGRect f = self.view.frame; scrollView.contentSize = f.size; f.origin.x = 0; f.origin.y = 0; scrollView.frame = f; [self.view addSubView:scrollView]; 

finalmente, si “pierde” su vista de desplazamiento en el constructor de interfaz (es posible cerrarlo para que desaparezca de la cuadrícula de diseño), no entre en pánico. simplemente haga clic en la lista de objetos a la izquierda de la cuadrícula de diseño.

En Xcode 4.5 usando Autolayout no tengo sección de Ingreso de contenido en mi inspector de tamaño. Así que tuve que agregarlo en Atributos de tiempo de ejecución definidos por el usuario y luego funcionó bien.

Lo que agrega en “Atributos de tiempo de ejecución definidos por el usuario” es keyPath == contentInset que es del tipo “Rect” (UIEdgeInsets, que tiene la misma entrada que Rect) y se define como {top, left}, {bottom, right}. ContentSize solo define la región de la ventana de desplazamiento. contentInset define el área desplazable.

Espero que esto ayude a alguien en la misma situación.

Muchas de las respuestas anteriores son engañosas o desactualizadas. A partir de 2017 (posiblemente mucho antes), el constructor de interfaz admite scrollviews con contenido de tamaño automático. El truco es que XCode le da un significado especial, no estándar a las restricciones entre la vista de desplazamiento y el contenido dentro de ella. Estas restricciones “internas” en realidad no afectarán el tamaño del contenido como usted podría esperar.

Esto significa que puede, por ejemplo, tener su vista de desplazamiento fijada en la parte inferior de la vista principal con margen cero, y también tener el contenido de su scrollview fijado a la parte inferior de la vista de desplazamiento con margen cero, pero el contenido en realidad no se extenderá. En cambio, el contenido obtendrá su tamaño autodeterminado (más abajo) y este también será el tamaño del área desplazable dentro de la vista de desplazamiento.

Piénselo de esta manera: existe una asimetría en las restricciones vinculantes de una vista de desplazamiento: las restricciones de la vista de desplazamiento hacia el mundo “exterior” (principal) determinan el tamaño y la posición de la vista de desplazamiento como de costumbre. Pero las restricciones “dentro” de la vista de desplazamiento realmente establecen el tamaño y la posición del área desplazable de la vista de desplazamiento, al vincularla al contenido.

Esto no es totalmente obvio porque cuando va a configurar las restricciones, XCode siempre sugerirá el espaciado actual y puede que nunca se le ocurra cambiar intencionalmente las restricciones hacia adentro y hacia fuera de una manera que entre en conflicto. Pero puede y tienen el significado descrito anteriormente: uno controla el diseño de la vista de desplazamiento y otro controla el tamaño del área de contenido desplazable.

Me encontré con esto por accidente y luego viendo cómo parecía funcionar, me llevó a este artículo que lo explica completamente y cita la fuente de documentos de Apple para esto:

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

Una última información importante, sobre el tamaño autodeterminado del contenido: puede sentir que está en un catch-22 aquí porque normalmente dimensiona su contenido, por ejemplo, el ancho de la vista principal, pero en este caso el elemento principal es la vista de desplazamiento y como se describió anteriormente, la restricción no afectará el tamaño de su contenido. La respuesta aquí es recordar que puede restringir elementos a elementos que no están directamente al lado de su jerarquía de vistas: por ejemplo, puede establecer el ancho de su vista de contenido al ancho de la vista principal en lugar de intentar en vano que la vista de desplazamiento lo haga para ti.

Si hace clic en el ícono Propiedades de cualquier Controlador de Vista en el Creador de Interfaces, puede establecerlo en un tamaño de “Forma libre” en Métrica Simulada y cambiar el tamaño de la Vista principal para que sea el tamaño de su contenido deseado.

De esta forma, puede crear el contenido de su ScrollView como si fuera una gran vista. Como solo se trata de una métrica simulada, tu View Controller se redimensionará a los límites de la ventana cuando se cargue.

La configuración de UIScrollView a través de Interface Builder no es intuitiva. Aquí está mi lista de verificación para configurarlo:

  1. Seleccione el archivo XIB de UIViewController. En el “Inspector de identidad” del constructor de interfaz, cambie UIView a clase tipo UIScrollView

  2. Debajo de “File Inspector”, desmarque Autolayout

  3. En “Inspector de atributos”, cambie el tamaño a Forma libre. A continuación, puede estirar la vista de desplazamiento manualmente o puede especificar un ancho y una altura personalizados en “Inspector de tamaño”.

  4. En “Identity Inspector”, agregue un nuevo atributo de tiempo de ejecución definido por el usuario llamado “contentSize” de tipo “Tamaño” y cámbielo a un valor como {320, 1000}. Ya no puede establecer esto programáticamente y, por lo tanto, necesita este paso para que la vista de desplazamiento sepa que el contenido de la vista de desplazamiento es más grande que la ventana.

Simplemente elimine el autoLayout en su vista de desplazamiento. entonces el código es tan simple como esto:

 scrollviewName.contentSize = CGSizeMake(0, 650); 

simplemente cree una propiedad iboulet en el archivo .h y luego sintetice en el archivo .m. Asegúrese de que el desplazamiento esté habilitado.

Sí, st3fan tiene razón, se debe establecer la propiedad contentSize de UIScrollView. Pero no debes apagar el diseño automático para este propósito. Puede configurar fácilmente contentSize de UIScrollView con autolayout solo en IB, sin ningún código.

Es importante comprender que cuando se utiliza el contenido de autolayout, el tamaño de UIScrollView no se establece directamente, sino que se calcula según las restricciones de todas las subvistas de UIScrollView. Y todo lo que necesita es proporcionar restricciones adecuadas para las subvistas en ambas direcciones.

Por ejemplo, si solo tiene una subvista, puede establecer su altura y espacio desde la parte superior e inferior a la supervista (es decir, scrollView en nuestro caso) contentSize.height se calcula como sum

 Vertical Space (aSubview.top to Superview.top) + aSubview.height + Vertical Space (aSubview.top to Superview.top) 

contentSize.width se calcula de forma similar a las restricciones horizontales.

Si hay muy pocas restricciones para calcular el tamaño del contenido correctamente, se muestra un pequeño botón rojo cerca de la opción Ver escena del controlador para informar sobre la ambigüedad del diseño.

Si hay muchas subvistas, puede tratarse de una “cadena” de restricciones: subvista superior a superior, alturas y espacios entre las subvistas y la subvista inferior a la inferior, como en la respuesta de Danyal Aytekin .

Pero en la práctica, en la mayoría de los casos es más conveniente agregar una vista vacía con el tamaño requerido y establecer espacios en la parte superior, izquierda, inferior, derecha de scrollView en 0. Puede usar esta vista como “vista de contenido”, es decir, poner todas las otras subvistas en él o si ya tiene muchas subvistas y no quiere moverlas y configurar el diseño de nuevo, puede agregar esta vista auxiliar a las subvistas existentes y ocultarlas.

Para hacer scrollView, el contenido calculado desplazable debe ser mayor que el tamaño de scrollView.

Puede tener UIScrollView en StoryBoard con Autolayouts. Básicamente, lo que necesitas es:

  1. Agregar UIScrollView
  2. Agregue todas las restricciones al mismo (como las inserciones de los bordes superior, izquierdo, derecho e inferior)
  3. Agregue un UIView ‘contenedor’ a UIScrollView
  4. Si solo desea un desplazamiento en una dirección (por ejemplo, vertical): establezca la altura explícitamente (para la instancia, 600) y el ancho del enlace con el ancho de UIScrollView.
  5. Si desea desplazamiento en dos direcciones, simplemente ajuste ancho y alto.

configuración del guión gráfico

Aquí hay una solución para diseñar ScrollView con un contenido más grande que la pantalla enteramente en Storyboard (bueno, casi en su totalidad, necesitarás agregar 1 sola línea de código también)

https://stackoverflow.com/a/19476991/1869369

Descubrí una manera más conveniente.

1: Escala el tamaño de la vista de desplazamiento para contener todo el UI dentro de él.

2: Agregue un iboutlet de la vista de desplazamiento.

3: en viewDidLoad, guarde el frame.size de la vista de desplazamiento.
(por ejemplo _scrollSize = _scrollView.frame.size;)

4: en viewWillAppear, configure el contentSize por el CGSize que guardó antes.
(por ejemplo _scrollView.contentSize = _scrollSize;)

5: Hecho ~

  1. Agregar UIViewController
  2. En UIViewController ‘Attribute Inspector -> Simulated Metrics’ establece el tamaño Freeform
  3. En UIViewController ‘Size Inspector -> View Controller’ establece altura 800
  4. Agregar UIScrollView en UIViewController
  5. Agregue todas las restricciones a UIScrollView (arriba, izquierda, derecha, abajo) y agregue la alineación X = centro
  6. Agregue UIView en UIScrollView
  7. Agregue todas las restricciones a UIView (arriba, izquierda, derecha, abajo) y agregue la alineación X = centro. Sí, lo mismo que para UIScrollView en # 3, pero para UIView
  8. Agregue la restricción de altura a UIView. Por ejemplo 780
  9. correr

Storyboard

Crea un nuevo proyecto Xcode

Navega al archivo Main.storyboard

Seleccione ScrollView de la biblioteca de objetos.

Establecer el marco para el ScrollView.

Agregue otra vista para desplazarse por la vista y mantenga el marco igual al de ScrollView.

Ahora, para establecer su altura y ancho dinámicamente, puede configurar esto con un UIScrollView usando el diseño automático en XIB