iphone - ¿Cómo agregar userInfo a un UIAlertView?
objective-c nsdictionary (5)
¿Me gustaría saber cómo agregar un objeto UserInfo, o cualquier NSDictionary, a un UIAlertView?
Gracias.
Funciona para mí si le doy una cadena c literal como "clave" en lugar de crear un carácter estático
En su lugar, teniendo en cuenta lo que dice Anomie, podrías hacer esto:
objc_setAssociatedObject ( alert , (const void*)0x314 , notification , OBJC_ASSOCIATION_RETAIN ) ;
Esto funciona para cualquier cosa que le permita usar un vacío arbitrario * (observación, esta función, etc.) y no requiere trucos de variables estáticas adicionales. Además, (const void *) 0x314 SIEMPRE es 0x314, no importa lo que haga el compilador.
Además, Anomie, me acabas de ahorrar MUCHO trabajo en una aplicación en la que estoy trabajando ahora mismo. ¡Gracias!
Escribí una categoría (bien probada) en NSObject
que le da a cada objeto la capacidad de almacenar datos fácilmente.
Simplemente coloque el código en un archivo de encabezado e implementación e impórtelo en cualquiera de sus proyectos. O ponerlo en una biblioteca estática. Mac OS X 10.6+ y iOS (¿versión?) Solamente.
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
@interface NSObject (CCFoundation)
- (id)associativeObjectForKey: (NSString *)key;
- (void)setAssociativeObject: (id)object forKey: (NSString *)key;
@end
#pragma mark -
@implementation NSObject (CCFoundation)
static char associativeObjectsKey;
- (id)associativeObjectForKey: (NSString *)key {
NSMutableDictionary *dict = objc_getAssociatedObject(self, &associativeObjectsKey);
return [dict objectForKey: key];
}
- (void)setAssociativeObject: (id)object forKey: (NSString *)key {
NSMutableDictionary *dict = objc_getAssociatedObject(self, &associativeObjectsKey);
if (!dict) {
dict = [[NSMutableDictionary alloc] init];
objc_setAssociatedObject(self, &associativeObjectsKey, dict, OBJC_ASSOCIATION_RETAIN);
} [dict setObject: object forKey: key];
}
@end
En pocas palabras, cada objeto se convierte en un diccionario fácil de usar (gracias a NSMutableDictionary
) tan pronto como lo necesite. El diccionario se libera cuando el objeto es y los objetos del diccionario se liberan cuando se libera el diccionario. Es increíble cómo Apple hizo esto simple.
Advertencia 1: El código anterior está habilitado para ARC . Está bien probado y se utiliza en varios productos enviados. No he visto ninguna pérdida de memoria o problemas de rendimiento.
Advertencia 2: cambie el nombre de los métodos como desee, pero si elige mantener el nombre, asegúrese de agregar un prefijo. Esta es una categoría en un objeto raíz, personas. ¡Alguna clase en algún lugar está usando este nombre de método y no quieres interferir! Mi biblioteca estática que setAssociativeCCObject:forKey:
en cada proyecto usa los nombres de métodos associativeCCObjectForKey:
y setAssociativeCCObject:forKey:
Espero que esto ayude a cualquiera que desee tener una simple userInfo
similar a userInfo
en cada objeto. ¡De nada! :-)
He encontrado una solución más simple que puede encajar en algunas circunstancias. Debido a que obtiene el contexto NSAlertView cuando se llama al delegado, uso la dirección real del objeto para crear una etiqueta (NSString *) que luego utilizo para almacenar valores personalizados en un NSDictionary global o específico del objeto. Aquí hay un ejemplo:
+(NSString*)GetTag:(id)ObjectIn
{
return [NSString stringWithFormat:@"Tag-%i",(int)ObjectIn];
}
En el delegado:
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSString* MyID = [CommandManager GetTag:alertView];
[CurrentActiveAlerts removeObjectForKey:MyID];
}
Vocación:
UIAlertView *myAlert = [[UIAlertView alloc] initWithTitle:title_text
message:@""
delegate:self
cancelButtonTitle:nil
otherButtonTitles:button_text ,nil];
CurrentActiveAlerts[[CommandManager GetTag:myAlert]] = CommandToRun;
[myAlert show];
[myAlert release];
Las teclas terminarán pareciéndose a "Tag-226811776". Espero que esto ayude.
Puede intentar subclasificar UIAlertView para agregar el campo, o almacenar una referencia en su clase de delegado. Pero la forma más general de adjuntar cualquier objeto a cualquier otro objeto es usar objc_setAssociatedObject
.
Para hacerlo, tiene que #import <objc/runtime.h>
, y necesita un void *
arbitrario que se usa como una clave (el truco habitual es declarar un static char fooKey;
en su archivo .m y usar su dirección). Entonces puedes adjuntar el objeto así:
objc_setAssociatedObject(alertView, &fooKey, myDictionary, OBJC_ASSOCIATION_RETAIN);
En este caso, myDictionary se conservará durante la vida útil de alertView y se liberará cuando se desasigne alertView.
Para recuperar su objeto asociado más adelante, use el objc_getAssociatedObject
nombre objc_getAssociatedObject
.
NSDictionary *myDictionary = objc_getAssociatedObject(alertView, &fooKey);
Devuelve nil
si no hubo ningún conjunto de asociación. Para romper la asociación, solo use objc_setAssociatedObject
para asociar un nuevo valor para el mismo objeto y clave; nil
se puede usar para romper la asociación sin asociar un nuevo objeto.
Otros valores para el tipo de asociación además de OBJC_ASSOCIATION_RETAIN se enumeran here .
Si está en> iOS 4.0 (para bloques) y solo quiere uno o dos botones, puede usar esta categoría que hice:
https://github.com/rsaunders100/UIAlertView-Blocks
Evita la necesidad de agregar información del usuario ya que pone su función de manejo de clics directamente en la alerta. p.ej
#import UIAlertView+Blocks.h
...
...
NSString* myUserInfo = @"example";
[UIAlertView displayAlertWithTitle:@"Example Alert View With Blocks"
message:nil
leftButtonTitle:@"Ok"
leftButtonAction:^{
NSLog(@"%@", myUserInfo);
}
rightButtonTitle:nil
rightButtonAction:nil];