目标C:向UIButton调用的方法发送参数

我有一个在单击UIButton时调用的方法。 当我创建按钮时,我希望它将NSTimer存储为参数。

这是计时器和UIButton的创建。 如何添加定时器以发送到方法? 我试过withObject:timer但它在运行时给了我一个警告和崩溃。

 NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:(0.009) target:self selector:@selector(moveStickFig:) userInfo:stickFig repeats:YES]; [stickFig addTarget:self action:@selector(tapFig:andTime:) forControlEvents:UIControlEventTouchUpInside]; 

这是我发送给它的方法:

 -(void) tapFig:(id)sender andTime:(NSTimer *)timer 

在定义了UIButton之后,我还尝试了[stickFig performSelector:@selector(tapFig:andTime) withObject:nil withObject:timer] ,但这也会导致警告和崩溃。

您不能 – 不使用参数调用UIControl 操作选择器 ,作为操作源的控件,或作为操作源的控件以及在该控件上发生的UIEvent。 在IB中,您必须将UIButton连接到这样的方法:您不能添加任何其他自定义参数。

如果您希望它可以访问其他对象,则它们必须是实例变量。

如果您想了解如何定义实例变量,请查看Apple的Objective C简介 。

您可以采用扩展UIButton的方法。

 @interface MyButton : UIButton @property (nonatomic, retain) NSDictionary *userInfo; @end 

那你的方法

 - (void)foo:(MyButton *)sender{ NSLog(@"%@", [sender.userInfo valueForKeyPath:@"extraData"]); } 

并设置userInfo

 ... MyButton *myButton = (MyButton *)[UIButton buttonWithType:UIButtonTypeCustom]; //set up a dictionary with info, called userInfo myButton.userInfo = userInfo; [myButton addTarget:self selector:@selector(foo:) forControlEvent:UIControlEventTouchUpInside]; 

这对你有用吗?

修改您的方法以将单个NSArray作为参数。 然后,创建参数数组并将其传递给performSelector

更清楚:

您将创建控件事件所需的IBAction ,以及将NSArray作为参数的第二个方法。 调用IBAction方法时,它会在创建NSArray参数后调用第二个方法。 把它想象成一个“方法链”。

我建议创建一个小型支持类,它就像一个委托,只需为您处理点击操作,然后更改addTarget方法的目标。

首先创建您的支持类:

 @interface ClickDelegate : NSObject { NSTimer timer; } @property (nonatomic, assign) NSTimer *timer; - (void)clickAction:(id)sender; @end @implementation ClickDelegate @synthesize timer; - (void)clickAction:(id)sender { // do what you need (like destroy the NSTimer) } @end 

然后改变目标:

 // In your view controller NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:(0.009) target:self selector:@selector(moveStickFig:) userInfo:stickFig repeats:YES]; // Instantiate a new delegate for your delegate action // and set inside of it all the objects/params you need ClickDelegate *aDelegate = [[ClickDelegate alloc] init]; aDelegate.timer = timer; [stickFig addTarget:aDelegate action:@selector(clickAction:) forControlEvents:UIControlEventTouchUpInside]; self.myDelegate = aDelegate; // as suggested in the comments, you need to retain it [aDelegate release]; // and then release it 

通过这种方式,您可以将单击回调委托给另一个对象。 这种情况非常简单(您只需要获取NSTimer实例),但在复杂场景中,它还可以帮助您通过将不同的东西委托给不同的小类来设计应用程序逻辑。

希望这可以帮助! 再见

您需要将计时器作为视图控制器的属性,然后从tapFig:方法引用它。 以下是您的代码的外观:

MainViewController.h

 // // MainViewController.h // TapFigSample // // Created by Moshe Berman on 1/30/11. // Copyright 2011 MosheBerman.com. All rights reserved. // @interface MainViewController : UIViewController { NSTimer *timer; UIButton *stickFig; } @property (nonatomic, retain) NSTimer *timer; @property (nonatomic, retain) UIButton *stickFig; - (void)tapFig:(id)sender; - (void) moveStickFig; - (void) moveStickFig:(id)yourArgument @end 

MainViewController.m

 // // MainViewController.m // TapFigSample // // Created by Moshe Berman on 1/30/11. // Copyright 2011 MosheBerman.com. All rights reserved. // #import "MainViewController.h" @implementation MainViewController @synthesize timer, stickFig; - (void) viewDidLoad{ [self setTimer:[NSTimer scheduledTimerWithTimeInterval:(0.009) target:self selector:@selector(moveStickFig:) userInfo:stickFig repeats:YES]]; [stickFig addTarget:self action:@selector(tapFig:) forControlEvents:UIControlEventTouchUpInside]; } - (void)tapFig:(id)sender{ //do something with self.timer } - (void) moveStickFig:(id)yourArgument{ //Move the stick figure //A tophat and a cane might //look nice on your stick figure // :-) } - (void)dealloc { [stickFig release]; [timer release]; [super dealloc]; } @end 

请注意头文件中的@property声明。 我也考虑再看看定时器初始化,但那可能就是我。 我希望这有帮助!

您可以创建UIButton的子类,在此子类中添加属性,将对象存储在此属性中,并通过发送方获取操作方法。