La 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:
- 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ásdelegate
que programar!
Este es el forma de usar AlertMessage
:
Asi de simple. Les copio el .h y .m para que puedan probarlo y mejorarlo.
//
// 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:
alertMessageWithOKCancel
, etc. etc.cancelButtonIndex
de UIAlertView
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
Deja una respuesta
Lo siento, debes estar conectado para publicar un comentario.