将parameter passing给addTarget:action:forControlEvents
我正在使用addTarget:action:forControlEvents像这样:
[newsButton addTarget:self action:@selector(switchToNewsDetails) forControlEvents:UIControlEventTouchUpInside]; 
我想将parameter passing给我的select器“switchToNewsDetails”。 我成功做的唯一的事情是通过写(ID)发送者:
 action:@selector(switchToNewsDetails:) 
但我想传递整数值的variables。 用这种方式来写就行不通了:
 int i = 0; [newsButton addTarget:self action:@selector(switchToNewsDetails:i) forControlEvents:UIControlEventTouchUpInside]; 
用这种方式写这个也不行:
 int i = 0; [newsButton addTarget:self action:@selector(switchToNewsDetails:i:) forControlEvents:UIControlEventTouchUpInside]; 
任何帮助将不胜感激:)
 action:@selector(switchToNewsDetails:) 
 您不会将parameter passing给switchToNewsDetails:方法。 您只需创build一个select器,使button在发生某些操作时可以调用它(触摸您的情况)。 控件可以使用3种types的select器来响应动作,它们都具有预定义的参数: 
- 
没有参数
action:@selector(switchToNewsDetails) - 
1个参数表示发送消息的控件
action:@selector(switchToNewsDetails:) - 
有2个参数表示发送消息的控件和触发消息的事件:
action:@selector(switchToNewsDetails:event:) 
目前还不清楚你究竟做了什么,但是考虑到你想为每个button分配一个特定的详细信息索引,你可以执行以下操作:
- 为每个button设置一个标签属性等于所需的索引
 - 
在
switchToNewsDetails:方法中你可以获得该索引并打开适当的deatails:- (void)switchToNewsDetails:(UIButton*)sender{ [self openDetails:sender.tag]; // Or place opening logic right here } 
要传递自定义参数与button单击您只需要SUBCLASS UIButton 。
(ASR打开,所以代码中没有任何发布。)
这是myButton.h
 #import <UIKit/UIKit.h> @interface myButton : UIButton { id userData; } @property (nonatomic, readwrite, retain) id userData; @end 
这是myButton.m
 #import "myButton.h" @implementation myButton @synthesize userData; @end 
用法:
 myButton *bt = [myButton buttonWithType:UIButtonTypeCustom]; [bt setFrame:CGRectMake(0,0, 100, 100)]; [bt setExclusiveTouch:NO]; [bt setUserData:**(insert user data here)**]; [bt addTarget:self action:@selector(touchUpHandler:) forControlEvents:UIControlEventTouchUpInside]; [view addSubview:bt]; 
接收function:
 - (void) touchUpHandler:(myButton *)sender { id userData = sender.userData; } 
如果您需要我对上述代码的任何部分更具体,请随时在评论中提出。
Target-Action允许三种不同forms的动作select器:
 - (void)action - (void)action:(id)sender - (void)action:(id)sender forEvent:(UIEvent *)event 
我根据上面的信息提出了一个解决scheme。 我只是将titlelabel.text设置为我想传递的string,并设置titlelabel.hidden = YES
喜欢这个 :
 UIButton *imageclick = [[UIButton buttonWithType:UIButtonTypeCustom] retain]; imageclick.frame = photoframe; imageclick.titleLabel.text = [NSString stringWithFormat:@"%@.%@", ti.mediaImage, ti.mediaExtension]; imageclick.titleLabel.hidden = YES; 
这样,就不需要inheritance或类别,并且没有内存泄漏
我为数组中的每个电话号码创build了几个button,因此每个button都需要一个不同的电话号码来呼叫。 我使用setTag函数,因为我正在for循环中创build几个button:
 for (NSInteger i = 0; i < _phoneNumbers.count; i++) { UIButton *phoneButton = [[UIButton alloc] initWithFrame:someFrame]; [phoneButton setTitle:_phoneNumbers[i] forState:UIControlStateNormal]; [phoneButton setTag:i]; [phoneButton addTarget:self action:@selector(call:) forControlEvents:UIControlEventTouchUpInside]; } 
然后在我的电话:方法我使用相同的循环和一个if语句来select正确的电话号码:
 - (void)call:(UIButton *)sender { for (NSInteger i = 0; i < _phoneNumbers.count; i++) { if (sender.tag == i) { NSString *callString = [NSString stringWithFormat:@"telprompt://%@", _phoneNumbers[i]]; [[UIApplication sharedApplication] openURL:[NSURL URLWithString:callString]]; } } } 
您可以通过button对象本身传递任何您想要的数据(通过访问CALayers keyValue字典)。
像这样设置你的目标(用“:”)
 [myButton addTarget:self action:@selector(buttonTap:) forControlEvents:UIControlEventTouchUpInside]; 
将您的数据添加到button本身,如下所示:
 NSString *dataIWantToPass = @"this is my data";//can be anything, doesn't have to be NSString [myButton.layer setValue:dataIWantToPass forKey:@"anyKey"];//you can set as many of these as you'd like too! 
然后当button被点击时,你可以这样检查:
 -(void)buttonTap:(UIButton*)sender{ NSString *dataThatWasPassed = (NSString *)[sender.layer valueForKey:@"anyKey"]; NSLog(@"My passed-thru data was: %@", dataThatWasPassed); } 
由于这里提到的解决方法有很多种,除了类别function。
使用类别function将定义的(内置)元素扩展到您的可定制元素中。
例如(ex):
 @interface UIButton (myData) @property (strong, nonatomic) id btnData; @end 
在你的视图Controller.m中
  #import "UIButton+myAppLists.h" UIButton *myButton = // btn intialisation.... [myButton set btnData:@"my own Data"]; [myButton addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; 
事件处理器:
 -(void)buttonClicked : (UIButton*)sender{ NSLog(@"my Data %@", sender. btnData); } 
看到我上面的评论,我相信你有不止一个参数时使用NSInvocation
更多关于NSInvocation的信息
http://cocoawithlove.com/2008/03/construct-nsinvocation-for-any-message.html
这解决了我的问题,但它崩溃,除非我改变
 action:@selector(switchToNewsDetails:event:) 
至
 action:@selector(switchToNewsDetails: forEvent:) 
你可以用一个闭包(Objective-C中的块)replacetarget-action,方法是添加一个helper闭包(ClosureSleeve)并将其作为一个关联对象添加到控件中,以便保留它。 这样你可以传递任何参数。
Swift 3
 class ClosureSleeve { let closure: () -> () init(attachTo: AnyObject, closure: @escaping () -> ()) { self.closure = closure objc_setAssociatedObject(attachTo, "[\(arc4random())]", self, .OBJC_ASSOCIATION_RETAIN) } @objc func invoke() { closure() } } extension UIControl { func addAction(for controlEvents: UIControlEvents, action: @escaping () -> ()) { let sleeve = ClosureSleeve(attachTo: self, closure: action) addTarget(sleeve, action: #selector(ClosureSleeve.invoke), for: controlEvents) } } 
用法:
 button.addAction(for: .touchUpInside) { self.switchToNewsDetails(parameter: i) } 
我在CustomButton中分类了UIButton,并添加了一个属性来存储我的数据。 所以我打电话给方法:( CustomButton *)发件人和方法我只读取我的数据sender.myproperty。
示例CustomButton:
 @interface CustomButton : UIButton @property(nonatomic, retain) NSString *textShare; @end 
方法操作:
 + (void) share: (CustomButton*) sender { NSString *text = sender.textShare; //your work… } 
分配行动
  CustomButton *btn = [[CustomButton alloc] initWithFrame: CGRectMake(margin, margin, 60, 60)]; // other setup… btnWa.textShare = @"my text"; [btn addTarget: self action: @selector(shareWhatsapp:) forControlEvents: UIControlEventTouchUpInside];