I have a method that is being called when a UIButton is clicked. When I create the button I want it to store an NSTimer as an argument.
This is the timer and the cr
Modify your method to take a single NSArray
as an argument. Then, create your array of parameters and pass it to performSelector
.
To be more clear:
You would create the IBAction
required for the control's event and a second method that takes an NSArray
as an argument. When the IBAction
method is called, it would call the second method after creating the NSArray
of parameters. Think of it as a "method chain."
You need to make the timer a property of your view controller and then referenced it from your tapFig:
method. Here is what your code might look like:
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
Notice the @property
declaration in the header file. I'd consider taking another look at the timer initialization too, but that could just be me. I hope this helps!
You can create subclass of UIButton, add property in this subclass, store your object in this property and get it in action method through sender.
You can't - UIControl action selectors are invoked with no parameters, the control that is the source of the action, or the control that is the source of the action and the UIEvent which occurred on that control. In IB you have to connect the UIButton to such a method: you can't add any other custom parameters.
If you want it to have access to other objects, they need to be instance variables.
Review Apple's Introduction to Objective C if you want to understand how to define instance variables.
You could take the approach where you extend UIButton.
@interface MyButton : UIButton
@property (nonatomic, retain) NSDictionary *userInfo;
@end
Then your method
- (void)foo:(MyButton *)sender{
NSLog(@"%@", [sender.userInfo valueForKeyPath:@"extraData"]);
}
And to set 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];
Would that work for you?
I suggest to create a small support class that works like a delegate that simply takes care of the click action for you, then change the target of your addTarget
method.
@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
In this way you're delegating the click callback to another object. This case is really simple (you just need to get the NSTimer instance) but in a complex scenario it also helps you to design the application logic by delegating different stuff to different small classes.
Hope this helps! Ciao