How do you pass a variable to the UIAlertView delegate?

落爺英雄遲暮 提交于 2019-11-30 12:33:44

问题


How do you pass a variable to the UIAlertView delegate?

I have a variable that I want to use in the alert view delegate. It is only used in the function that shows the UIAlertView and the UIAlertView delegate, so i don't think it should be a property on the controller. Is there a way to attach the variable to UIAlertView and retrieve it in the delegate?

- (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];
    }                                 
}

回答1:


in .h before interface:

extern const char MyConstantKey;
@interface ViewController...

in .m import:

import <objc/runtime.h>

in .m before implementation

const char MyConstantKey;

in .m implementation

-(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);

 }

in .m alertview callback

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

     NSString *associatedString = objc_getAssociatedObject(alertView, &MyConstantKey);

     NSLog(@"associated string: %@", associatedString);

}



回答2:


Use Associated Objects. It is described in more detail here: Your New Friends: Obj-C Associated Objects

To set the object you use use:

objc_setAssociatedObject(alert, &key, userCode, OBJC_ASSOCIATION_RETAIN);

And then to get it back:

SOCode *userCode = objc_getAssociatedObject(alertView, &key);

You also need to add static char key; so that it is in the scope of moth methods.

Update

I have wrapped this into a category on UIAlertView. You can use Cocoapods to bring it in:

pod 'HCViews/UIAlertViewHCContext', '~> 1.2'

The source is available here: https://github.com/hypercrypt/HCViews/blob/master/Categories/UIAlertView%2BHCContext.h




回答3:


A lot of posts talk about the concepts behind associated objects (which is good!) but sometimes you just want to see the code. Here's a clean and quick category that you can either put in a separate file or above the interface of one of your existing .m files (you could even replace UIAlertView with NSObject and effectively add a context property to any object):

#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

And then you'll be able to do something like:

NSObject *myObject = [NSObject new];

UIAlertView *alertView = ...
alertView.context = myObject;

IMPORTANT: And don't forget to nil the context in dealloc!!




回答4:


UIAlertView is a subclass of UIView which has a tag property you can set to an integer. Unfortunately if you need something other than an integer to identify/pass info to the delegate than you will need to set some properties (or set up an array with the tag indexing into it) on the delegate itself. Advaith's way will probably work but is technically not supported by 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];



回答5:


I suspect the most straight-forward way is a property in the alert view's delegate class. An alert view doesn't have any provision for "user info" and doesn't support sub-classing, which removes the only shortcuts that come to mind.




回答6:


Subclass UIAlertView, add a property called userInfo with type of your choice. Set the user info value at the time you create an instance of Subclassed UIAlertView, and retrieve it from within the delegate method. (There you will get the subclassed instance which holds the userInfo)



来源:https://stackoverflow.com/questions/10387862/how-do-you-pass-a-variable-to-the-uialertview-delegate

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!