Desarrollo iOS: AlertMessage, una forma de mejorar UIAlertView

24/10/2011 por Redacción

34305_640.jpgLa primera vez que vi la clase UIAlertView se me paralizó la respiración. Miré la documentación oficial, busqué snippets de código por internet... y sí, era así nomas. No podía creer que para poner un simple mensaje que tuviera un par OK/Cancel, tenía que dividir mi código en 2 partes!, es que para enterarme si el usuario presiono un botón u otro hay que colgarse de un delegate. Yo entiendo, tiene toda la lógica, pero tener que separar algo que naturalmente va junto, no me gusta nada. Y la cosa empeora si hay más de un Alert en nuestro Controller: el resultado de cada uno de ellos llega a la misma función del delegate, por lo cual, algo que es feo de por sí, termina siendo además caótico!

Eran tiempos de iOS 3 y no se me ocurrió una buena forma de mejorarlo. Pero con iOS 4 y los code-blocks, la solución llegó. Por eso les presento un wrapper llamado AlertMessage, que soluciona los dos problemas que no me dejaban dormir:

  1. código compacto: el código a ejecutar luego del alerta se define en el mismo lugar donde se crea el AlertMessage y no en otro lugar.

no hay “bolsa de gatos”: no hay un delegate centralizado donde caen todos los Alertas, porque no hay más delegate que programar!

Este es el forma de usar AlertMessage:

creo el objeto

le asigno título y mensaje

le defino los botones

le defino el código que debe ejecutarse al momento en que se presionen cualquier de los botones

listo, momento de visualizar el Alert: show

Asi de simple. Les copio el .h y .m para que puedan probarlo y mejorarlo.

AlertMessage.h

//

// AlertMessage.h

//

#import <Foundation/Foundation.h>

typedef void (^AlertMessageHandler)(int);

@interface AlertMessage : NSObject

@property (nonatomic, retain) NSString* titulo;

@property (nonatomic, retain) NSString* mensaje;

+ (id)alertMessage;

- (void)show;

- (void)agregarBoton:(NSString*)_texto;

- (void)ejecutarCodigo:(AlertMessageHandler)_codigo;

@end

AlertMessage.m

//

// AlertMessage.m

//

#import "AlertMessage.h"

@interface AlertMessage () <UIAlertViewDelegate>

{

UIAlertView* alert;

AlertMessageHandler codigo;

}

- (id)init;

@end

@implementation AlertMessage

@synthesize titulo, mensaje;

- (void)dealloc

{

self.titulo = nil;

self.mensaje = nil;

Block_release(codigo);

[alert release];

[super dealloc];

}

// Para el usuario, AlertMessage tiene una semantica similar a un autorelease: lo construye pero nunca lo mata. En realidad esto lo consigo suicidándolo en el delegate

// Debido a esto, el Code Analizer reporta un posible leak, asi que uso esta directiva para evitar que analice este método

#ifndef __clang_analyzer__

+(id)alertMessage;

{

return [[AlertMessage alloc] init]; // no hago autorelease, porque se "suicida" en el delegate

}

#endif

-(id)init;

{

self = [super init];

if (self) {

alert = [[UIAlertView alloc] init];

alert.delegate = self;

}

return self;

}

// aquí termino de completar el UIAlertView y lo displayo

-(void)show;

{

alert.title = self.titulo;

alert.message = self.mensaje;

[alert show];

}

// delego en addButtonWithTitle

-(void)agregarBoton:(NSString*)_texto;

{

[alert addButtonWithTitle:_texto];

}

// me quedo con la instancia de codigo a ejecutar cuando se cierra el UIAlertView

- (void)ejecutarCodigo:(AlertMessageHandler)_codigo;

{

codigo = Block_copy(_codigo);

}

#pragma mark -

#pragma mark Alert view delegate

- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {

// si hay codigo a ejecutar, lo hago

if (codigo) {

codigo(buttonIndex);

}

[self release]; // aquí se mata a si mismo

}

@end

Entre las mejoras, se me ocurren:

crear varios constructores, considerando los usos más habituales, como alertMessageWithOKCancel, etc. etc.

soporte para la propiedad cancelButtonIndex de UIAlertView

soporte en iOS 5 de la propiedad alertViewStyle de UIAlertView (propiedad muy interesante, que da la interfaz para poner un campo de texto en el alerta, algo que tarde o temprano vas a necesitar).

Hasta la próxima!

Un artículo de Angel Traversi

0

Comentarios

No se ha enviado aún ningún comentario. ¡Tú puedes ser el primero en comentarlo!

Escribe un comentario

Regístrate o identifícate para poder comentar