iOS UIButton 点击事件带多参数

iOS 原生的 UIButton 点击事件是不允许带多参数的,唯一的一个参数就是默认UIButton本身

那么我们该怎么实现传递多个参数的点击事件呢?


1.如果业务场景非常简单,要求传单参数并且是整数类型,可以用tag

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. [cell.deleteButton setTag:indexPath.row];  //例如,将cell的行数设置成tag  



2.利用ObjC关联,runtime之所以被称为iOS 的动态特性是有道理的,当然关联甚至可以帮助NSArray等其他对象实现“多参数传递”

实现起来也非常简便:

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. UIButton *btn = // create the button  
  2. objc_setAssociatedObject(btn, "firstObject", someObject, OBJC_ASSOCIATION_RETAIN_NONATOMIC);   //实际上就是KVC  
  3. objc_setAssociatedObject(btn, "secondObject", otherObject, OBJC_ASSOCIATION_RETAIN_NONATOMIC);  
  4.   
  5. [btn addTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside];  
  6.   
  7. - (void)click:(UIButton *)sender  
  8. {  
  9.     id first = objc_getAssociatedObject(btn, "firstObject");        //取参  
  10.     id second = objc_setAssociatedObject(btn, "secondObject");  
  11.     // etc.  
  12. }  



3.利用自定义,添加一个多参数的字典属性变量即可(为什么要字典?可以装多多的)

自定义Button子类,甚至都不用重写啥的:

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. @interface MultiParamButton : UIButton  
  2.   
  3. @property (nonatomicstrong) NSDictionary* multiParamDic;  
  4.   
  5. @end  


传参:

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. NSDictionary* paramDic = @{@"one":@"one"@"two":@2@"third":@(3)};  
  2.   
  3. MultiParamButton* multiParamButton = [[MultiParamButton alloc] init];  
  4. [multiParamButton setFrame:CGRectMake(005050)];  
  5. multiParamButton.center = self.view.center;  
  6. [multiParamButton setBackgroundColor:[UIColor grayColor]];  
  7. [multiParamButton addTarget:self action:@selector(multiParamButtonClicked:) forControlEvents:UIControlEventTouchUpInside];  
  8. [self.view addSubview:multiParamButton];  
  9.   
  10. multiParamButton.multiParamDic = paramDic;  

点击:

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. - (void)multiParamButtonClicked:(UIButton* )button  
  2. {  
  3.     MultiParamButton* multiParamButton = (MultiParamButton* )button;  
  4.       
  5.     NSLog(@"Vvvverify : %@", multiParamButton.multiParamDic);  
  6. }  

爽爽的:


当然,如果用扩展,然后添加property后重写GetSet也是一样一样的



4.完全不在Button上入手,针对业务来,最常见的就是在TableViewCell上面的Button,这种存在(视图)继承树之间的传递,这里举个简单的例子

Button获取所属父视图的所属视图控制器的参数,间接传参

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #import "LBMultiParamButtonController.h"  
  2.   
  3. #import "MultiParamButton.h"  
  4.   
  5. @interface LBMultiParamButtonController ()  
  6.   
  7. @property (nonatomicstrong) NSDictionary* paramDic;  
  8.   
  9. @end  
  10.   
  11.   
  12. @implementation LBMultiParamButtonController  
  13.   
  14. - (id)init  
  15. {  
  16.     self = [super init];  
  17.   
  18.     if (self)  
  19.     {  
  20.         _paramDic = @{@"one":@"one"@"two":@2@"third":@(3)};  
  21.     }  
  22.       
  23.     return self;  
  24. }  
  25.   
  26. - (void)viewDidLoad  
  27. {  
  28.     [super viewDidLoad];  
  29.       
  30.     UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];  
  31.     [button setFrame:CGRectMake(005050)];  
  32.     [button setCenter:self.view.center];  
  33.     [button setBackgroundColor:[UIColor grayColor]];  
  34.     [button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];  
  35.     [self.view addSubview:button];  
  36. }  
  37.   
  38. - (void)buttonClicked:(UIButton* )button  
  39. {  
  40.       
  41.     LBMultiParamButtonController* multiParamButtonController = nil;  
  42.       
  43.     //获取button所属的视图控制器,如果视图控制器都能获取,还有什么不能获取呢?  
  44.     for(UIView* next = [button superview]; next; next = next.superview)  
  45.     {  
  46.         UIResponder *nextResponder = [next nextResponder];  
  47.           
  48.         if ([nextResponder isKindOfClass:[LBMultiParamButtonController class]])  
  49.         {  
  50.             multiParamButtonController = (LBMultiParamButtonController* )nextResponder;  
  51.               
  52.             break;  
  53.         }  
  54.     }  
  55.       
  56.     NSLog(@"param : %@", multiParamButtonController.paramDic);  
  57. }  
  58.   
  59. @end  

这种非常多的用在UITableViewCell上自定义的按钮的参数的情况!



5.利用Delegate和performSelector:withObject:withObject  方法可以传递最多两个参数:

定义protocol:

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #pragma mark - SYAccountListCellDelegate.  
  2.   
  3. @class SYAccountListCell;  
  4.   
  5. @protocol  SYAccountListCellDelegate <NSObject>  
  6.   
  7. - (void)accountListCell:(SYAccountListCell* )cell didTapButton:(UIButton* )button;  
  8.   
  9. @end  

自定义Cell的时候将你想传的东西传进入,这里用cell和button做例子:

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. @implementation SYAccountListCell  
  2.   
  3. - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier  
  4. {  
  5.     self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];  
  6.       
  7.     if (self)  
  8.     {  
  9.           
  10.         self.deleteButton = [UIButton buttonWithType:UIButtonTypeCustom];  
  11.         [self.deleteButton setFrame:CGRectMake(225,  
  12.                                                5,  
  13.                                                40,  
  14.                                                40)];  
  15.         [self.deleteButton setBackgroundColor:[UIColor redColor]];  
  16.         [self.deleteButton addTarget:self action:@selector(deleteButtonClicked:) forControlEvents:UIControlEventTouchUpInside];  
  17.         [self.contentView addSubview:self.deleteButton];  
  18.     }  
  19.       
  20.     return self;  
  21. }  
  22.   
  23. - (void)deleteButtonClicked:(UIButton* )button  
  24. {  
  25.     if ([self.delegate respondsToSelector:@selector(accountListCell:didTapButton:)])  
  26.     {  
  27.         [self.delegate performSelector:@selector(accountListCell:didTapButton:) withObject:self withObject:button];  
  28.     }  
  29. }  
  30.   
  31. @end  


Delegate实现:

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #pragma mark - SYAccountListCellDelegate.  
  2.   
  3. - (void)accountListCell:(SYAccountListCell *)cell didTapButton:(UIButton *)button  
  4. {  
  5.     NSLog(@"Cell : %@ , Button : %@", cell, button);  
  6. }  


虽然有点曲折,但是传参效果非常到位


这里补充一下,这里的最多两个参数是直面的参数个数,如果将参数设置位结构体,那么就皆大欢喜啦,想怎么传就怎么传!



6.利用Block 和  关联 , 直接可以当前点击并且操作参数 - 强!

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #import <UIKit/UIKit.h>  
  2.   
  3. typedef void (^ActionBlock)();  
  4.   
  5. @interface UIButton (Utility)  
  6.   
  7. @property (readonlyNSMutableDictionary *event;  
  8.   
  9. - (void) handleControlEvent:(UIControlEvents)controlEvent withBlock:(ActionBlock)action;  
  10.   
  11. @end  

实现文件:

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #import <objc/runtime.h>  
  2. #import "UIButton+Utility.h"  
  3.   
  4. @implementation UIButton (Utility)  
  5.   
  6. static char overviewKey;  
  7.   
  8. @dynamic event;  
  9.   
  10. - (void)handleControlEvent:(UIControlEvents)event withBlock:(ActionBlock)block  
  11. {  
  12.     objc_setAssociatedObject(self, &overviewKey, block, OBJC_ASSOCIATION_COPY_NONATOMIC);  
  13.       
  14.     [self addTarget:self action:@selector(callActionBlock:) forControlEvents:event];  
  15. }  
  16.   
  17.   
  18. - (void)callActionBlock:(id)sender  
  19. {  
  20.     ActionBlock block = (ActionBlock)objc_getAssociatedObject(self, &overviewKey);  
  21.       
  22.     if (block)  
  23.     {  
  24.         block();  
  25.     }  
  26. }  
  27.   
  28. @end  


操作:

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. [button handleControlEvent:UIControlEventTouchUpInside withBlock:^{  
  2.   
  3.     NSLog(@"ssss : %@"self.paramDic);  
  4.   
  5. }];  
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值