Tutorial - Patrón Delegate en iOS – Guía

Duración:
30'
Nivel:
intermedio
Curso relacionado:
iOS 16

En este tutorial vamos a aprender a implementar el patrón delegate. Este patrón se utiliza en objetos habituales a la hora de programar en iOS, por ejemplo, al hacer uso de un objeto UITableView, lo habitual es hacer uso de un controlador para que sea su delegate, e implementamos los métodos correspondientes, como por ejemplotableView:didSelectRowAtIndexPath:.

Para empezar vamos a crear un nuevo proyecto de tipo Single View Application. En este caso vamos a hacer uso tanto de ARC como de storyboards, por lo que marcamos ambas casillas.

El siguiente paso que vamos a realizar es crear un nuevo controlador. Recordad que al usar storyboards no es necesario que creemos el fichero XIB.

Ahora vamos a ir al storyboard y añadir un nuevo View Controller para representar el controlador que acabamos de crear. Indicamos que dicho View Controller corresponderá a nuestro controlador.

Para poder conectar nuestros dos controladores añadimos un botón en el primero de ellos y mediante control-click o click derecho creamos un segue de tipo push hasta el segundo controlador. Debemos de añadir por lo tanto un Navigation Controller. Lo realizaremos desde el menú Editor tal y como se muestra en la siguiente imagen.

Recordad añadir un identificador al segue puesto que nos será útil más adelante. Si ejecutamos la aplicación podremos comprobar el funcionamiento del botón, que provocará que se muestre el segundo controlador.

En este segundo controlador vamos a añadir tres botones, también vamos a crear los métodos correspondientes en el fichero .m

  • (IBAction)firstButton:(id)sender {NSLog(@"First button pressed");}

  • (IBAction)secondButton:(id)sender {NSLog(@"Second button pressed");}

  • (IBAction)thirdButton:(id)sender {NSLog(@"Third button pressed");}

    Recordad enlazarlos en el storyboard, de lo contrario no funcionarán. Podemos probar la aplicación y ver como se muestran los mensajes por pantalla.

    Vamos ahora a programar el patrón delegate. En este caso lo emplearemos para decirle al controlador principal que botón se ha pulsado. Para ello, deberemos escribir en el fichero .h de nuestro segundo controlador el siguiente código.

    #import

@protocol AnotherViewControllerDelegate;

@interface AnotherViewController : UIViewController

@property (assign, nonatomic) id delegate;

@end

@protocol AnotherViewControllerDelegate

- (void)anotherViewController:(AnotherViewController *)anotherViewController firstButtonPressed:(id)sender;
- (void)anotherViewController:(AnotherViewController *)anotherViewController secondButtonPressed:(id)sender;@optional
- (void)anotherViewController:(AnotherViewController *)anotherViewController thirdButtonPressed:(id)sender;

@end

Podemos observar en el código que hemos declarado un protocolo llamado AnotherViewControllerDelegate, y que también se han detallado los métodos.

Con este código indicamos que existe un delegate llamado AnotherViewControllerDelegate mediante el cual se deben implementar los métodos anotherViewController:firstButtonPressed: y anotherViewController:secondButtonPressed: mientras que el métodoanotherViewController:thirdButtonPressed: es opcional y por tanto los delegates no están obligados a implementarlo. Se puede ver también que se ha declarado una propiedad para el delegate de este controlador, por lo que deberemos realizar el synthesize correspondiente.

Vamos a ir al controlador principal ahora y ha modificar el .h de la siguiente manera.

#import

import "AnotherViewController.h"

@interface ViewController : UIViewController

@end

Por otro lado, en el .m añadimos el método prepareForSegue: y a hacer Build a continuación.

  • (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {if ([segue.identifier isEqualToString:@"MySegue"]) {((AnotherViewController* )segue.destinationViewController).delegate = self;}}

Podremos comprobar ahora que se nos muestran tres warnings en nuestro controlador principal. Esto se debe a que hemos indicado que se corresponde con el protocolo AnotherViewControllerDelegatepero no implementa sus método. Por lo tanto vamos a implementarlos.

Únicamente añadiendo estas líneas nos libraremos de los warnings.

  • (void)anotherViewController:(AnotherViewController *)anotherViewController firstButtonPressed:(id)sender {NSLog(@"First button delegate method");}

  • (void)anotherViewController:(AnotherViewController *)anotherViewController secondButtonPressed:(id)sender {NSLog(@"Second button delegate method");}

    Vamos a cambiar ahora los métodos de los botones por lo siguiente:

    • (IBAction)firstButton:(id)sender {NSLog(@"First button pressed");[delegate anotherViewController:self firstButtonPressed:sender];}
    • (IBAction)secondButton:(id)sender {NSLog(@"Second button pressed");[delegate anotherViewController:self secondButtonPressed:sender];}

    Con esta nueva línea en cada método estamos indicando que se llame a dicho método del delegate del controlador. Si ejecutamos ahora la aplicación y pulsamos los botones se nos mostrará tanto el mensaje del método del botón, como el mensaje del método del delegate.

    Vamos a realizar lo mismo con el botón restante.

  • (void)anotherViewController:(AnotherViewController *)anotherViewController thirdButtonPressed:(id)sender {NSLog(@"Third button delegate method");}

  • (IBAction)thirdButton:(id)sender {NSLog(@"Third button pressed");[delegate anotherViewController:self thirdButtonPressed:sender];}Una vez eliminado, si compilamos no se nos muestra ningún error puesto que se había indicado que era opcional. El problema viene a la hora de ejecutar la aplicación. La ejecutamos y fallará al pulsar el tercer botón.

    Si lo pulsamos, el comportamiento debe ser exactamente el mismo que con los otros dos. Si recordamos como hemos declarado los métodos, hemos dicho que el métodoanotherViewController:thirdButtonPressed: era opcional, por lo que vamos a realizar una prueba y vamos a eliminar la implementación del controlador principal.

    https://www.imaginaformacion.com/tutoriales/tutorial_39_imagen_1.png

    Este error se produce porque estamos llamando a un método que no está implementado. Para solucionar esto podemos hacer uso del método respondsToSelector: que permite comprobar si un objeto implementa el método indicado.

    • (IBAction)thirdButton:(id)sender {NSLog(@"Third button pressed");if ([delegate respondsToSelector:@selector(anotherViewController:thirdButtonPressed:)]) {[delegate anotherViewController:self thirdButtonPressed:sender];}}

    Al ejecutar ahora la aplicación no fallará puesto que se comprueba previamente si existe dicho método y en caso de no existir no se realiza la llamada correspondiente.

    Mediante este patrón podemos informar a otros controladores de la ejecución de nuestros métodos, la finalización de un proceso como la conexión con un servidor, e incluso, pasar objetos y datos al controlador anterior para que en caso necesario puedan actualizar la información o interfaz.

Solicita información sobre iOS 16

En Imagina llevamos más de 13 años ofreciendo formación para empresas, estamos especializados en el área técnica y de ofimática, adaptando nuestras formaciones a vuestras necesidades. Déjanos tus datos, y nos pondremos en contacto contigo para informarte sobre el curso que mejor se ajuste a lo que buscas. Cuéntanos tus necesidades y podremos asesorarte sobre la modalidad que mejor se adapte: En directo, En directo a Medida u Online.

España