Seguramente has visto algunas aplicaciones en las que hay un botón que, al apretarlo, despliega un menú con otros botones (a los que podríamos llamar secundarios). El botón principal, se le suele denominar FAB o Float Action Button. En este artículo vamos a ver cómo se crea un FAB Button con Swift, que al apretarlo despliegue (con una animación) un menú.

Además, desarrollaremos este botón como un paquete Swift, de forma que podamos compartirlo incluirlo como dependencia en diferentes aplicaciones. Esto lo haremos mediante Swift Package Manager, que como ya vimos en un artículo anterior, es el gestor de dependencias de Apple.

El código de este artículo lo puedes encontrar en GitHub. Ten en cuenta puede haber algunas modificaciones en el código del repositorio respecto al que se describe aquí, ya que, se pueden añadir nuevas funcionalidades, mejorar otras y, corregir pequeños errores.

Creación del paquete Swift

En primer lugar creamos el paquete Swift. Para ello, desde el menú de Xcode seguimos la ruta New > Swift Package y le damos el nombre de FABButton (recuerda activar el control de versiones, Create Git repository on my Mac, para poder subirlo luego a un repositorio en la red).

Creación del paquete Swift.

Este proyecto lo definiremos para ser utilizado en plataformas iOS10+. Esto lo indicaremos en el fichero Package.swift (tal como se explicó en un artículo anterior):

Diseño del componente

El diseño del componente será el siguiente:

FAB Button Swift Package Manager
Diseño del componente con sus subcompoenentes.

La vista principal esta formada por un componente UIStackView, que contendrá el botón principal (componente UIButton) y un segundo componente UIStackView, que será el que contenga los botones secundarios, cada uno de los cuales estará etiquetado (conn un componente UILabel). El hecho de utilizar componentes UIStackView se debe tanto a su capacidad de distribuir los elementos que contiene como de adaptarse a su contenido.

Desarrollo de la vista principal

La vista principal la cramos en el directorio Sources/FABButton con el nombre FABView. Inicialmente, en esta vista definiremos y colocaremos los componenes que la forman: el botón principal y el componente UIStackView que contendrá los botones secundarios:

En este código hemos hecho lo siguiente:

  • En primer lugar instanciamos un componte UIButton y un componente UIStackView.
  • Después establecemos un inicializador personalizado para poder indicar la imagen del botón principal:

De la misma forma que la clase FABStackView, este inicializador también lo declaramos como público, para poder acceder a él una vez lo importenemos como dependencia. Dentro del inicializador establedemos la imagen del botón y le asociamos su target (mainButtonAction). Después llamamos al método configure(), que será el que configure los diferentes componentes y los sitúe en la vista:

En la configuración del componente UIStackView, hemos indicado que los elementos (botones secundarios) que contenga se dispongan verticalmente, se alineen a la derecha (trailing), llenen todo el espacio (el componente UIStackView crecera al añadis botones) y que entre ellos haya una separación de 16).

Configuración del botón principal

El botón principal que hemos creado, mainButton, es un simple botón cuadrado con una imagen en su interior. Para hacer que se parezca a un botón FAB hemos de hacerlo redondo y con sombra.

Para ello lo que haremos será crear una subclase de UIButton con las características que le queramos dar al botón. Lo que hacemos es:

  • Desde el menú de Xcode creamos un nuevo fichero (File > New > File…) y seleccionamos Cocoa Touch Class.
FAB Button Swift Package Manager
  • Cuando nos aparece la ventana de opciones del nuevo fichero (Choose options for your new file:), indicamos como nombre para el fichero FABMainButton, que será una subclase de UIButton:
FAB Button Swift Package Manager
  • Por defecto, el código que aparece en esta clase es:
  • En primer lugar añadiremos los inicializadores:
  • Al final del método init se llama al método configure(), que será en el que personalizaremos el botón.
  • Tal como se puede observar, lo que hacemos es darle color blanco al fondo del botón, hacerlo redondo al indicar que el radio de las esquinas es de 25 (la mitad del tamaño de botón, que es de 50) y, como estamos utilizando auto layout, indicamos que translatesAutoresizingMaskIntoConstraints = false.
  • Al final de este método se llama al método que creará la sombra del botón:

Una vez creada esta subclase de UIButton, vamos a la clase FABView y cambiamos la forma que en hemos instaciado el botón principal. Pasamos de:

A:

Creación de los botones secundarios

Los componentes del menú están formados por un botón (con una imagen personalida) y un etiqueta con el identificador del botón. Para crear estos componentes utilizaremos una subclase de UIView en la que definiremos el botón y la etiqueta.

  • Desde el menú de Xcode creamos un nuevo fichero (File > New > File…) y seleccionamos Cocoa Touch Class (tal como hemos hecho con el componente FABMainButton).
  • Cuando nos aparece la ventana de opciones del nuevo fichero (Choose options for your new file:), indicamos como nombre para el fichero FABSecondaryButton, que será una subclase de UIView:
FAB Button Swift Package Manager

Por defecto, el código que aparece en esta clase es:

Inicialmente creamos un componente UIButton, un componente UILabel y un componte UIView sobre el que situaremos el componte UILabel (y que nos permitirá dar el efecto de sombra a la etiqueta):

Para hacer que las etiquetas se adapten al ancho de su contenido, pero incluyendo un cierto margen, en vez de utilizar directamente el componente UILabel, hacemos una subclase de este (a la que llamamos FABInsetLabel). En esta subclase, lo que hacemos es modificar el ancho de la etiqueta añadiendo un cierto valor que podemos especificar:

Como al presionar el botón secundario se deberá producir una acción, estableceremos un protocolo para poder pasar la acción y un delegado dentro de la clase:

Además, crearemos un inicializador personalizado que nos permita pasar la imagen del botón, el texto de la etiqueta y la acción a realizar. Para simplificar todos estos parámetros, utilizaremos typealias para unificar estos parámetros e instanciaremos una variable con este tipo:

Ahora ya podemos completar la clase que hemos creado, que quedará de la siguiente manera (se han simplificado las partes que ya habíamos preparado anteriormente):

Creación del menú de botones secundarios

El menú de botones secundarios lo crearemos, tal como hemos inidcado en el diseño del componente, con un componente UIStackView. Para ello lo que haremos será crear una subclase de UIStackView con las características que le queramos darle. Lo que hacemos es:

  • Desde el menú de Xcode creamos un nuevo fichero (File > New > File…) y seleccionamos Cocoa Touch Class (tal como hemos hecho con el componente FABMAinButton).
  • Cuando nos aparece la ventana de opciones del nuevo fichero (Choose options for your new file:), indicamos como nombre para el fichero FABStackView, que será una subclase de UIStackView:
FAB Button Swift Package Manager

Por defecto, el código que aparece en esta clase es:

Primero añadimos el inicializador y la configuración del componente UIStackView:

Básicamente, lo que hacemos es decir que lo elementos que introduzcamos en este componente se situarán verticalmente, alineados a la derecha y con una separación de 12.

Para añadir botones secundarios añadiremos dos métodos: el primero añadirá un botón y el segundo, los configurará todos en la vista. Estos dos métodos, los colocaremos en una extensión para estructurar el código:

Dado que realizaremos animaciones para añadir y eliminar los botones, mantendremos dos listas (arrays) con estos botones: la que contiene los botones añadidos y que no se modifica posteriormente (secondaryViews), y la que contiene una copia de estos botones para añadirlos o borrarlos y generar la animación (secondaryButtons):

Animación de los botones secundarios al aparecer y desaparecer

Para hacer que la presentación y ocultación de los botones secundarios sea un poco más vistosa, añadiremos animaciones tanto a la hora de mostrarlo como a la hora de ocultarlos.

Presentación de los botones

La presentación de los botones se hará de uno en uno, y se buscará un efecto de rebote en dicha aparición. Esto lo haremos concatenando tres animaciones seguidas sobre el mismo botón:

  • Para empezar, transformamos la vista del botón y la etiqueta con una escala de 0.001.
  • La primera animación lo transforma con una escala de 1.1 en 0.075 segundos. Es decir, el botón se hace un 10% más grande de su tamaño final.
  • La segunda animación lo escala hasta 0.9 en 0.03 segundos (un 90% de su tamaño final).
  • Finalmente, lo transfomramos a su tamaño real en 0.03 segundos.

Todo esto, en conjunto, da un efecto rebote en la aparición del botón. Además, cuando se completa la animación final se llama de forma recursiva a este método, de forma que se van presentando los botones uno a uno (observa cómo al principio del método usamos la copia de los botones para extraerlos y eliminarlo a la vez que los mostramos).

Ocultación de los botones

Para ocultar los botones haremos algo parecido a lo comentado anteriormente para su presentación, per ahora solo utilizaremos una animación, en la que durante 0.075 segundos se pase del tamaño original a una escala de 0.001, para luego eliminar el boton de la vista:

Adopción del protocolo FABSecondaryButtonDelegate

Como los botones secundarios pasas su acción mediante un delegado y el protocolo FABSecondaryButtonDelegate, hemos de hacer que la clase FABStackView adopte el método de este protocolo (lo hacemos mediante una extension para tener ordenado el código):

Es decir, cuando hagamos clic en un botón secundario, se ejecutará este método. En este punto se dan dos pasos:

  • Primero se pasa la acción mediante un delegado a la clase que ha instanciado FABStackView (es decir, la clase principal FABView). Para que pueda hacerlo, al principio de la clase FABStackView hemos de añadir un delegato del protocolo:
  • En segundo lugar, llamamos al método dismissButtons, para que se oculten los botones secundarios.

De forma simplificada (en los métodos), el código de esta clase queda de la siguiente forma:

Para finalizar, hemos de hacer que la clase FABView también adopte el protocolo FABSecondaryButtonDelegate, de forma que pueda ejecutar pasar la acción del botón secundario que se ha seleccionado:

Ahora simplmente hemos de subir todo el código introducido a un repositorio(en este caso, GitHub) para que este disponible para ser utilizado como dependencia en cualquier aplicación.

Cómo importar el FAB Button en un proyecto

Para importar el paquete Swift que contiene el FAB Button, lo primero que hacemos es crear un proyecto nuevo en Xcode.

Una vez creado, vamos al menú de Xcode File > Swift Packages > Add Package Dependency…

FAB Button Swift Package Manager

Luego indicamos la dirección URL del paquete Swift:

FAB Button Swift Package Manager

E indicamos la versión o rama que queremos añadir:

FAB Button Swift Package Manager

Una vez añadido, en el menú de navegación podemos ver el paquete ya importado:

FAB Button Swift Package Manager

Ahora, en la clase ViewController solo necesitamos importar el componente, configurar la vista y añadir los botones. Por ejemplo, el siguiente código muestra un botón con cuatro botones secundarios:

Si ahora ejecutamos esta aplicación, podemos comprobar el funcionamiento del FAB Button.

Conclusiones

En este artículo hemos visto como crear un FAB Button que muestra un menú secundario y, además, crearlo como un paquete Swift para poder subirlo a repositorio y compartirlo con otros proyectos. Desde que en Xcode 11 se ha incorporado Swift Package Manager, este proceso se ha vuelto mucho más sencillo.


0 comentarios

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Sígueme en Feedly
shares