如何将变量传递给 UIAlertView 委托?

Posted

技术标签:

【中文标题】如何将变量传递给 UIAlertView 委托?【英文标题】:How do you pass a variable to the UIAlertView delegate? 【发布时间】:2012-04-30 17:25:47 【问题描述】:

如何将变量传递给UIAlertView 委托?

我有一个要在警报视图委托中使用的变量。它仅用于显示UIAlertViewUIAlertView 委托的函数中,所以我认为它不应该是控制器上的属性。有没有办法将变量附加到UIAlertView 并在委托中检索它?

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

【问题讨论】:

How to add userInfo to a UIAlertView? 的可能重复项 【参考方案1】:

在接口前的.h中:

extern const char MyConstantKey;
@interface ViewController...

在 .m 中导入:

import <objc/runtime.h>

实施前的.m

const char MyConstantKey;

在 .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);

 

在.m alertview 回调中

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

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

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


【讨论】:

为什么我们需要 .h 中的 'extern const char MyConstantKey' 以及 .m 中的 const char MyConstantKey? 使用此解决方案时,请注意以下问题***.com/questions/21561211/… 我得到了 x86_64 架构的未定义符号:“_MyConstantKey”,引用自:【参考方案2】:

使用关联对象。这里有更详细的描述:Your New Friends: Obj-C Associated Objects

要设置你使用的对象:

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

然后将其取回:

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

您还需要添加static char key;,使其在moth方法的范围内。

更新

我已将其打包到UIAlertView 上的一个类别中。您可以使用 Cocoapods 将其引入:

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

来源在这里:https://github.com/hypercrypt/HCViews/blob/master/Categories/UIAlertView%2BHCContext.h

【讨论】:

【参考方案3】:

很多帖子都在讨论关联对象背后的概念(这很好!),但有时您只想查看代码。这是一个干净而快速的类别,您可以将其放入单独的文件中,也可以放在现有 .m 文件之一的界面上方(您甚至可以将 UIAlertView 替换为 NSObject 并有效地将 context 属性添加到任何对象):

#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

然后您将能够执行以下操作:

NSObject *myObject = [NSObject new];

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

重要提示: 并且不要忘记将dealloc中的上下文设为nil!!

【讨论】:

嗨,你是什么意思:“不要忘记将dealloc 中的上下文归零”?【参考方案4】:

UIAlertViewUIView 的子类,它有一个tag 属性,您可以将其设置为整数。不幸的是,如果您需要整数以外的东西来识别/将信息传递给委托,那么您将需要在委托本身上设置一些属性(或设置一个带有标签索引的数组)。 Advaith 的方式可能会奏效,但在技术上不受 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];

【讨论】:

这对于快速解决问题非常有用,但是如果:1.您不必传递整数而是字符串,并且 2.如果您有另一个具有不同操作的警报视图和你想根据它的标签来写它的动作吗?【参考方案5】:

我怀疑最直接的方法是警报视图的委托类中的属性。警报视图没有任何“用户信息”规定,也不支持子分类,这会删除唯一能想到的快捷方式。

【讨论】:

它确实支持子类化。 UIAlertView Doc -- UIAlertView 类旨在按原样使用,不支持子类化 @commentators:他没有建议继承 UIAlertView,而是向委托类添加一个属性(例如,使用 AlertView 的 ViewController)。我认为这是一个有效的选择。【参考方案6】:

子类 UIAlertView,添加一个名为 userInfo 的属性和您选择的类型。在创建 Subclassed UIAlertView 的实例时设置用户信息值,并从委托方法中检索它。 (在那里您将获得包含 userInfo 的子类实例)

【讨论】:

你不应该继承UIAlertView @hypercrypt:我想我知道你为什么说 UIAlertView 不应该被子类化,但你能分享你这么说的理由吗? (NVM 下面的评论说明了这一点) @hypercrypt 为什么说我们不应该继承 UIAlertView。我尝试了一个 eg,效果很好! 正如 Jeffery Thomas 在下面发布的,UIAlertView Class Reference:UIAlertView 类旨在按原样使用,不支持子类化。此类的视图层次结构是私有的,不得修改。 除了我上面的评论之外,虽然它可能适用于 ios 5,但可能不适用于 iOS 6、7 或 8。正如 Apple 明确告诉您不要继承 UIAlertView 他们保留权利将来改变它,例如把它变成一个类集群。如果他们这样做了,那么您的代码肯定会崩溃。

以上是关于如何将变量传递给 UIAlertView 委托?的主要内容,如果未能解决你的问题,请参考以下文章

UIAlertView 可以通过委托传递字符串和整数吗

如何在 iPhone 应用程序的不同文件中为 UIAlertview 设置委托

从委托 iOS 传递变量

UITextView 类中未调用 UIAlertView 委托方法

Swift:如何将从委托接收到的值传递给函数的完成块?

如何使用 DependencyService 和接口委托将 xamarin.android 特定功能的方法传递给 xamarin.forms?