fbpx
 

Domina Auto Layout como un experto [Parte 2]

Domina Auto Layout como un experto [Parte 2]

1. Introducción

En las últimas semanas en EfectoApple me he centrado en desarrollar algunos tutoriales sobre Auto Layout.

Si nunca antes has trabajado con Auto Layout, te recomiendo que eches un vistazo a los Tutoriales de Introducción. Puedes acceder a ellos desde aquí.

Si ya tienes algo de experiencia con Auto Layout y quieres dar un paso más y aprender a utilizarlo únicamente a través de código, te recomiendo que accedas a la primera parte de nuestro tutorial desde aquí.

Si ya has visitado antes estos tutoriales y lo único que quieres es que deje de darte la paliza y vaya al grano, pues ¡allá vamos!

En este artículo trataremos la segunda parte del tutorial Domina Auto Layout como un experto y seguiremos desarrollando algunos ejemplos que te permitirán comprender al 100% esta herramienta.

2. ¿Qué vamos a ver en este Tutorial?

En este tutorial desarrollaremos 3 ejemplos más, donde veremos lo útil que puede llegar a ser Auto Layout en nuestras aplicaciones.

Concretamente en estos ejemplos verás lo siguiente:

  • Utilizar el parámetro metrics para hacer nuestro código más legible
  • Hacer que una view se mantenga siempre a la misma distancia de su superview independientemente del dispositivo donde se ejecute nuestra app
  • Como hacer que el tamaño de una view esté en función de otra view diferente

¡Comenzamos!

3. Proyecto de Inicio

Para llevar a cabo la segunda parte del tutorial utilizaremos el mismo proyecto de inicio que utilizamos en la primera parte. Este proyecto tiene todo lo necesario para que puedas comenzar con el tutorial.

Puedes descargarlo desde aquí.

Una vez descargado, ábrelo y accede al fichero ViewController.m. Puedes ver que hay creadas dos propiedades:

Estas dos views serán con las que trabajemos en todos los ejemplos de este tutorial. Veremos como cambiar sus posiciones y sus tamaños, utilizando para ello Auto Layout directamente por código.

Además de estas dos propiedades, también puedes ver que hay un método setupViews:. Este método lo único que hace es crear las views redView y blueView y darles a cada una su color de fondo correspondiente.

Después establecemos esta propiedad de cada view a NO

Si no entiendes porque hacemos esto, puedes acceder a la primera parte del tutorial, donde está explicado.

Para organizar el código en nuestro proyecto, a medida que vamos avanzando en el tutorial, crearemos un método por cada uno de los ejemplos que realicemos.

Si ejecutas este proyecto, verás que no aparece nada en pantalla. Esto se debe a que, aunque las views ya han sido creadas, todavía no hemos especificado su tamaño, por lo que ahora mismo al tener un height = 0 y un width = 0, no aparecen en pantalla. Todavía no hemos especificado sus dimensiones, porque esto es precisamente lo que vamos a hacer a continuación en nuestro primer ejemplo.

4. Ejemplo I

En este primer ejemplo, nuestro objetivo es conseguir esto:

  • La redView debe tener las siguientes carácterísticas:
    • Debe medir 100×100
    • Debe estar a 20 pixeles del borde izquierdo de su superview
    • Debe estar a 120 pixeles del borde superior de su superview
  • La blueView debe tener las siguientes características:
    • Debe medir 100×150
    • Debe estar a 10 pixeles del borde derecho de redView

Como en los ejemplos que vimos en la primera parte de nuestro tutorial, estas medidas serán la base a la hora de utilizar VFL para crear nuestras constraints.

En estos ejemplos, lo que hacíamos era añadir directamente nuestras medidas en las sentencias VFL. Por ejemplo:

Como debes saber, esto no está considerado una buena práctica de programación. Debemos evitar utilizar números para especificar medidas en nuestro código. Dificultan la comprensión del código. Lo lógico es utilizar variables con nombres descriptivos.

En estos ejemplos sencillos, no suponen un problema, pero si estás desarrollando una app algo más compleja, puede que algún compañero tuyo no entienda de donde salen estos: 200, 150, 20, etc. Incluso tú, pasado algún tiempo puede que no recuerdes porque has utilizado estas medidas.

Para evitar esto a la hora de crear nuestras constraints, utilizaremos el parámetro metrics: del método constraintsWithVisualFormat:

Este parámetro nos permite hacer referencia a un diccionario, donde declararemos todas las medidas que vayamos a utilizar en nuestras constraints y les asociaremos un nombre descriptivo.

Vamos a utilizarlo directamente en nuestro ejemplo, que es la mejor forma de entenderlo.

Como hemos dicho que vamos a crear un método por cada uno de los ejemplos de este tutorial, lo primero que debes hacer es crear un nuevo método llamado example1:, justo a continuación del método setupViews:

A continuación irás viendo el código que debes ir añadiendo a este método.

Lo primero, como siempre es crear un diccionario que asocie una clave a las views que vamos a usar con VFL:

Utilizamos “redView” para identificar a nuestra view roja y “blueView” para identificar a nuestra view azul.

A partir de este punto, es donde utilizaremos el parámetro metrics. Lo que haremos será crear un diccionario, donde declararemos todas las medidas que vayamos a utilizar en nuestras constraints y les asociaremos un nombre descriptivo:

A partir de este momento, en lugar de utilizar las medidas directamente utilizaremos sus nombres. Ya no usaremos 150, usaremos blueHeight, ya no usaremos 20, usaremos leftMargin.

Después, crearemos las 2 constraints de tamaño (width y height) de cada una de las views:

Como ves, ya no aparecen números de medidas en nuestro código.

Una vez que hemos creado las 4 constraints de tamaño, debemos añadirlas a nuestras views:

En tutoriales anteriores, vimos que para definir correctamente las constraints de una view, necesitamos darle al Auto Layout la información suficiente para obtener el tamaño y la posición. Ya le hemos dado información del tamaño, así que nos falta especificar la posición de nuestras views:

Para acabar nuestro ejemplo, una vez que hemos creado las constraints de tamaño, tendremos que añadirlas a nuestra view.

OJO: En este caso, no debemos añadir las constraints a nuestra redView sino que tendremos que añadirlas a su superview. Esto es así debido a que es responsabilidad de la superview especificar las posiciones de sus views hijas. Recuerda siempre esto:
[caja-gris]Las constraints de tamaño hay que añadirlas a la propia view[/caja-gris]
[caja-roja]Las constraints de posición hay que añadirlas a su superview[/caja-roja]
Por tanto, añadiremos las constraints de posición a la superview de redView, que en este caso es self.view:

Una vez que hemos acabado nuestro Ejemplo I, para poder probarlo tendremos que llamar a nuestro método example1:. Para ello añade la siguiente linea al final del método viewDidLoad:

Ejecuta la aplicación y podrás ver que nuestras views se colocan exactamente donde hemos definido. Deberías obtener esto:

auto layout post12_imagen1

5. Ejemplo II

En este segundo ejemplo, trabajaremos únicamente con la redview.

  • La redView debe tener las siguientes carácterísticas:
    • Debe tener un height de 300 pixeles
    • Debe estar a una distancia de 100 pixeles del borde superior de su superview
    • Debe estar SIEMPRE a una distancia de 30 pixeles del extremo derecho e izquierdo de su superview. Da igual que el dispositivo esté en posición horizontal o vertical.

Si te das cuenta, no especificamos el width de nuestra redView, ya que si queremos que esté a 30 pixeles del extremo derecho e izquierdo de su superview, ya estamos definiendo su width de forma indirecta. Además, si lo piensas bien, este width variará en función del tamaño del dispositivo donde se esté ejecutando.

Al igual que hemos hecho antes, tendremos que crear un nuevo método llamado example2: que añadiremos a continuación de example1:

Dentro de este método tendrás que ir añadiendo el código que veremos a continuación.

Comenzamos por crear el array con la redView, no es necesario incluir la blueView:

Creamos nuestro diccionario con las medidas:

Después, especificamos las constraints de tamaño de la redView:

Añadimos estas constraints a redView:

A continuación, especificamos las constraints de posición de la redView:

Como puedes, ver, hemos seguido al pie de la letra las especificaciones del Ejemplo 2, para definir los VFL.

Para terminar, tendremos que añadir estas constraints. No hace falta que vuelva a repetir a que vista hay que añadir las constraints de posición, ¿no? 😉

Para poder ejecutar este Ejemplo 2, deberás comentar la linea del viewDidLoad: donde hacías la llamada al método example1: y añadir a continuación la llamada a nuestro método example2:. Es decir, tu método viewDidLoad: debería tener este aspecto para poder ejecutar el Ejemplo 2:

Ejecuta el proyecto y comprueba que la redView se coloca perfectamente en nuestra aplicación. Ahora, rota el simulador y comprueba que tanto en posición vertical, como en posición horizontal, nuestra redView se mantiene siempre a 30 pixeles de distancia de los bordes derecho e izquierdo del dispositivo.

Puedes verlo en la siguiente imagen:

auto layout post12_imagen2

6. Ejemplo III

En este último ejemplo, veremos algo que en muchas ocasiones puede ser muy útil. Vamos a hacer que el tamaño de una de nuestras views esté en función de la otra.

Haremos que el height de la blueView sea la mitad que el height de la redView y también, que el width de la blueView sea la mitad que el width de la redView.

Como siempre, tendrás que crear un nuevo método llamado example3: que añadiremos a continuación de example2:

Dentro de este método tendrás que ir añadiendo el código que veremos a continuación.

Comenzamos por crear el array con nuestra redView. En este ejemplo no hará falta que agreguemos la blueView a este array:

Creamos nuestro diccionario con las medidas:

Después, especificamos las constraints de posición de nuestra redView. (No, no me he confundido, en lugar de comenzar por las constrains de tamaño, esta vez comenzamos por las de posición, ahora verás por qué).

Si te fijas en el código que hemos escrito, en la primera constraint (constraint_pos_v) estamos diciendo que nuestra redView se coloque a 30 pixeles del borde superior de nuestra superview y a 30 pixeles del borde inferior de nuestra superview.

En la segunda constraint (constraint_pos_h) estamos especificando que nuestra redView se coloque a 10 pixeles del borde izquierdo de nuestra superview y a 10 pixeles del borde derecho de nuestra superview. Al especificar estas constraints, también estamos especificando el tamaño de nuestra redView, por lo que no sería necesario utilizar constraints de tamaño, ya que están implícitas en nuestras constraints de posición.

Nuestro siguiente paso es añadir las constraints de posición a nuestra superview:

Y por último, y aquí es donde viene la parte interesante, hacemos que blueView sea la mitad que redView. Para ello tendremos que utilizar el método constraintWithItem: de la clase NSLayoutConstraint:

Aquí tienes la explicación de lo que hemos hecho:

  • constraintWithItem: Especifica la view sobre la que vamos a aplicar la constraint, en este caso, sería nuestra blueView.
  • attribute: Especifica sobre que atributo queremos aplicar la constraint, en este caso, primero width y luego height.
  • relatedBy: Establece la relación entre los elementos, utilizamos la relación Equal, ahora verás por qué.
  • toItem: Especifica la view en la que nos fijamos para establecer la constraint, en este caso, como queremos poner blueView en función de redView, aquí tendremos que poner self.redView.
  • attribute: Establece el atributo de redView en el que nos fijamos para establecer la constraint, en nuestro caso, primero width y luego height
  • multiplier: Determina la relación entre las views. Como queremos que blueView sea la mitad que redView, usaremos 0.5. Si quisiéramos que fuera la cuarta parte, usaríamos 0.25.
  • constant: Este parámetro no lo usaremos en este caso. Simplemente sirve por si queremos sumarle un valor constante a nuestra constraint. Por ejemplo, si queremos que nuestra blueView sea la mitad + 20 pixeles, pondríamos aquí 20.

Como puedes ver, si queremos que un atributo de una view esté en función del atributo de otra view, estos son los parámetros que tendrás que establecer.

Hemos utilizado relatedBy:Equal y multiplier:0.5 porque queremos que tanto la height como la width de blueView sean la mitad que la height y la blueView de redView. Si hubiéramos querido que fueran la cuarta parte, habríamos usado relatedBy:Equal y multiplier:0.25.

Para poder ejecutar este Ejemplo 3, deberás comentar la linea del viewDidLoad: donde hacías la llamada al método example2: y añadir a continuación la llamada a nuestro método example3:. Es decir, tu método viewDidLoad: debería tener este aspecto para poder ejecutar el Ejemplo 3:

Ejecuta el proyecto y comprueba que obtienes el mismo resultado que en la siguiente imagen:

auto layout post12_imagen3

Si te das cuenta, nuestra blueView es exactamente la cuarta parte de nuestra redView. Esto se debe a que hemos especificado que su height y su width deben ser la mitad que el height y width de redView. Además si te fijas, verás que blueView aparece situada exactamente en la esquina superior izquierda de su superview. Esto se debe a que no hemos especificado sus constraints de posición y Auto Layout la coloca automáticamente en la esquina superior izquierda.

[caja-gris]Si no especificas las constraints de posición de una view, Auto Layout la ubica automáticamente en la esquina superior izquierda[/caja-gris]

Ahora te toca a ti

Si acabáramos el ejemplo aquí, nuestra blueView quedaría algo mal colocada en la parte superior izquierda de nuestra aplicación. Así que lo que vamos a hacer es lo siguiente. Vamos a especificar las constraints de posición de nuestra blueView, utilizando para ello el mismo método que hemos usado para crear sus constraints de tamaño: constraintWithItem:

Concretamente lo que queremos es que nuestra blueView quede completamente centrada dentro de nuestra redView.

De hecho, sería interesante que jugando con los parámetros del método constraintWithItem: fueras capaz de hacer esta parte tu solo. Así que voy a ocultar esta parte del código por si quieres intentarlo por tu cuenta.

Cuando estés preparado para ver el código que resolvería esto, solo tienes que pulsar en el botón Solución.

[ejercicio titulo = “Solución” num=”2″]

auto layout post12_imagen4

 

[/ejercicio]

Si añades este código justo al final de tu método example3 y ejecutas de nuevo tu aplicación, verás como hemos conseguido que nuestra blueView se coloque justo en el centro de redView:

auto layout post12_imagen5

8. Resumen Final

En esta segunda parte de nuestro tutorial hemos podido ver algunas cosas interesantes:

  • Como utilizar el parámetro metrics para hacer nuestro código más legible
  • Como hacer que una view se mantenga siempre a la misma distancia de su superview independientemente del dispositivo donde se ejecute nuestra app
  • Establecer el tamaño de una view en función de otra view
  • Como centrar una view dentro de otra view

Puedes descargar el proyecto completo que hemos desarrollado en este tutorial desde aquí.

9. Has terminado el Tutorial

Has llegado hasta el final de este tutorial, ¡FELICIDADES!

Como siempre, aquí tienes tu recompensa, el video chorra de la semana:

[ejercicio titulo = “Perro cabrón” num=”1″]
auto layout post12_imagen6
[/ejercicio]

10. ¿Dónde ir ahora?

Si no quieres perderte ningún tutorial de EfectoApple, puedes suscribirte a nuestra newsletter, a través del formulario que tienes al final de este post.

Si este artículo te ha parecido útil, por favor, compártelo en tus redes sociales, para que EfectoApple pueda llegar cada vez a más lectores.

Si tienes cualquier duda, puedes usar los comentarios de la parte inferior.

Etiquetas:
Sin comentarios

Escribe un comentario

10AppsIpad

Descarga las 10 Aplicaciones

Introduce tu Nombre y tu Email para recibir las Apps en tu Correo

Acabo de enviarte un email. Sigue las instrucciones para descargar las Aplicaciones. Puede que tengas que revisar tu buzón de correo no deseado. Gracias.