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á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
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 ()
{
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).
No hay comentarios:
Publicar un comentario