Comment passez-vous une variable au délégué UIAlertView
?
J'ai une variable que je souhaite utiliser dans le délégué de la vue des alertes. Il est uniquement utilisé dans la fonction qui affiche les délégués UIAlertView
et UIAlertView
. Je ne pense donc pas que cela devrait être une propriété du contrôleur. Est-il possible d'associer la variable à UIAlertView
et de la récupérer dans le délégué?
- (void) someUserCondition:(SOCode *)userCode {
if ([userCode warrentsConfirmation] > 0) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Title" message:@"Are you sure?" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK",nil];
[alert setAlertViewStyle:UIAlertViewStyleDefault];
//TODO somehow store the code variable on the alert view
[alert show];
}
}
- (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
if ([title isEqualToString:@"OK"]){
SOCode *userCode = //TODO somehow get the code from the alert view
[self continueWithCode:code];
}
}
en .h avant l'interface:
extern const char MyConstantKey;
@interface ViewController...
en importation .m:
import <objc/runtime.h>
en .m avant la mise en œuvre
const char MyConstantKey;
dans l'implémentation .m
-(void)viewDidAppear:(BOOL)animated{ //or wherever
NSString *aString = @"This is a string";
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Testing" message:@"test is test" delegate:self cancelButtonTitle:@"Okay" otherButtonTitles:nil];
[alert show];
[alert release];
objc_setAssociatedObject(alert, &MyConstantKey, aString, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
dans le rappel d'alerte en .m
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
NSString *associatedString = objc_getAssociatedObject(alertView, &MyConstantKey);
NSLog(@"associated string: %@", associatedString);
}
Utiliser des objets associés. Il est décrit plus en détail ici: Vos nouveaux amis: Obj-C Objets associés
Pour définir l'objet que vous utilisez, utilisez:
objc_setAssociatedObject(alert, &key, userCode, OBJC_ASSOCIATION_RETAIN);
Et puis pour le récupérer:
SOCode *userCode = objc_getAssociatedObject(alertView, &key);
Vous devez également ajouter static char key;
pour qu'il soit à la portée des méthodes moth.
J'ai inclus cela dans une catégorie sur UIAlertView
. Vous pouvez utiliser Cocoapods pour l’apporter:
pod 'HCViews/UIAlertViewHCContext', '~> 1.2'
La source est disponible ici: https://github.com/hypercrypt/HCViews/blob/master/Categories/UIAlertView%2BHCContext.h
Beaucoup de posts parlent des concepts derrière les objets associés (ce qui est bien!) Mais parfois vous voulez juste voir le code. Voici une catégorie propre et rapide que vous pouvez placer dans un fichier séparé ou au-dessus de l'interface de l'un de vos fichiers .m
existants (vous pouvez même remplacer UIAlertView
par NSObject
et ajouter efficacement une propriété context
à tout objet):
#import <objc/runtime.h>
@interface UIAlertView (Private)
@property (nonatomic, strong) id context;
@end
@implementation UIAlertView (Private)
@dynamic context;
-(void)setContext:(id)context {
objc_setAssociatedObject(self, @selector(context), context, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(id)context {
return objc_getAssociatedObject(self, @selector(context));
}
@end
Et ensuite, vous pourrez faire quelque chose comme:
NSObject *myObject = [NSObject new];
UIAlertView *alertView = ...
alertView.context = myObject;
IMPORTANT: Et n'oubliez pas de supprimer le contexte dans dealloc
!!
UIAlertView
est une sous-classe de UIView
qui a une propriété tag
que vous pouvez définir comme un entier. Malheureusement, si vous avez besoin d'autre chose qu'un entier pour identifier/transmettre des informations au délégué, vous devez définir certaines propriétés (ou configurer un tableau avec l'indexation de balise dessus) sur le délégué lui-même. La méthode d'Advaith fonctionnera probablement, mais n'est techniquement pas prise en charge par Apple.
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Title" message:@"Are you sure?" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK",nil];
[alert setAlertViewStyle:UIAlertViewStyleDefault];
alert.tag = SOMEINTEGER;
[alert show];
Je soupçonne que la méthode la plus simple consiste à utiliser une propriété dans la classe des délégués de la vue des alertes. Une vue d'alerte ne contient aucune disposition relative aux "informations utilisateur" et ne prend pas en charge les sous-classes, ce qui supprime les seuls raccourcis qui vous viennent à l'esprit.
Sous-classe UIAlertView, ajoutez une propriété appelée userInfo avec le type de votre choix. Définissez la valeur d'informations utilisateur au moment où vous créez une instance de UIAlertView de sous-classe et récupérez-la à partir de la méthode delegate. (Vous obtiendrez l'instance sous-classée qui contient l'utilisateur userInfo)