(Target: Object) not working for setting UIButton from outside viewController - objective-c

I can create the UIButton.
But the callback: target: object won't work within the current object. ??
I can only do "self.viewController" object, and can't do "self" for current object.
thx
#import <Foundation/Foundation.h>
#import "ViewController.h"
#class ViewController;
#interface CGuiSetup : NSObject
{
#public
ViewController *viewController;
}
- (void) Setup;
- (void) ButtonRespond:(UIButton*) btn;
#end
#import "CGuiSetup.h"
#implementation CGuiSetup
- (void) ButtonRespond:(UIButton*) btn
{
NSLog(#"ButtonRespond");
}
- (void) Setup
{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btn setFrame:CGRectMake(10,10,100,100)];
// But I want to call the following in the CGuiSetup object (self) instead... but it crashes out if I leave it as just "self"
[btn addTarget:self.viewController action:#selector(ButtonRespond:)
forControlEvents:UIControlEventTouchUpInside]; //works: for "self.viewController" if I put ButtonRespond in the ViewController
[btn addTarget:self action:#selector(ButtonRespond:)
forControlEvents:UIControlEventTouchUpInside]; //fails: for "self"
[self.viewController.view addSubview:btn];
}
#end
#import <UIKit/UIKit.h>
#import "CGuiSetup.h"
#class CGuiSetup;
#interface ViewController : UIViewController
{
CGuiSetup *guiSetup; //<---- had to take this out of the "viewDidLoad" method
}
#end
- (void)viewDidLoad
{
[super viewDidLoad];
guiSetup = [CGuiSetup alloc];
guiSetup->viewController = self;
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btn setFrame:CGRectMake(10,10,100,100)];
[btn addTarget:guiSetup action:#selector(ButtonRespond:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}

If you're using ARC, does any object have a retaining reference to CGuiSetup? I sounds like CGuiSetup is instantiated, creates (or maybe receives from another object) the viewController, adds the button to it and then gives the view controller to another object (perhaps by pushing it on a navController or setting it to be the root controller of the app)? Whatever the case is, CGuiSetup it being dealloc'd and the button is trying to send a message to an object that's already been destroyed. How/where is CGuiSetup created? What object retains a reference to it? That's probably where your problem is.
If you don't understand what retain/release is and/or you don't know what ARC is, you need to read Apple's memory management guide: https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html

That's probably because your object is destroyed, while _viewController still has retain count greater than 0 (so it's not destroyed). Balance you're retain/release count.

Related

iOS - Implementation of MVC-Pattern without Interface Builder

I'm creating a little MVC-sample-project as an iPhone-application in XCode, which is built completely with code and therefore doesn't use Interface Builder. First I'd like to show you the code I have so far.
Controller
The controller instantiates the model and the view and also contains a function which demonstrates the independency between model and view:
ViewController.h
#import <UIKit/UIKit.h>
#import "MainView.h"
#import "ProjectModel.h"
#interface ViewController : UIViewController
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
{
ProjectModel *model;
MainView *myMainView;
}
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
model = [[ProjectModel alloc] init];
myMainView = [[MainView alloc] initWithFrame:CGRectMake(0, 0, 320, 468)];
[self.view addSubview:myMainView];
//test function to illustrate that view and model are independent
[self calculate];
}
- (void)calculate
{
int result = [model operationWithNumber:3 andAnotherNumber:5];
[myMainView showResult:result];
}
#end
Model
The class ProjectModel is responsible for the model of the project and is in this example for the sake of simplicity only responsible for summing up two numbers:
ProjectModel.h
#import <Foundation/Foundation.h>
#interface ProjectModel : NSObject
-(int)operationWithNumber:(int)number1 andAnotherNumber:(int)number2;
#end
ProjectModel.m
#import "ProjectModel.h"
#implementation ProjectModel
-(int)operationWithNumber:(int)number1 andAnotherNumber:(int)number2
{
return (number1 + number2);
}
#end
View
The view-class creates all the elements of the view and contains a function which displays the result of a calculation in a label.
MainView.h
#import <UIKit/UIKit.h>
#interface MainView : UIView
{
UILabel *lblResult;
}
- (void)showResult:(int)result;
#end
MainView.m
#import "MainView.h"
#implementation MainView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
UILabel *lblTitle = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 280, 50)];
lblTitle.text = #"This is my View";
[self addSubview:lblTitle];
lblResult = [[UILabel alloc] initWithFrame:CGRectMake(20, 200, 280, 50)];
lblResult.text = #"Result will be displayed here.";
[self addSubview:lblResult];
}
return self;
}
- (void)showResult:(int)result
{
lblResult.text = [NSString stringWithFormat:#"Resultat: %d", result];
}
#end
My Question:
I hope you understood the code so far. Based on the code above, I'd like to implement a button in the view-class which should calculate and display two numbers when the users clicks this button. Thus when the user clicks the button, the calculate-function in the ViewController should be called. I created a button with the following code in MainView.m:
UIButton *btnCalculate = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btnCalculate setFrame:CGRectMake(20, 90, 280, 50)];
[btnCalculate setTitle:#"Calculate" forState:UIControlStateNormal];
[btnCalculate addTarget:self action:#selector(calculate:) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:btnCalculate];
The problem is this line in the code above:
[btnCalculate addTarget:self action:#selector(calculate:) forControlEvents:UIControlEventTouchUpInside];
how can I add a function from the controller as the action of the button. I know that the target should not be self, since the function should be called in the ViewController, but I have no idea how I could do that. Could anyone help me and tell me how I can solve this problem?
The only solution that I can see right now is that the complete GUI is created in the ViewController directly. But I don't think that this is a nice solution, since the main purpose of MVC is to avoid the mix of controller and view code in the same class.
Also I'm wondering whether this code generally conforms to the MVC-pattern propagated by Apple, since I'm pretty new to this design-pattern. I'd really appreciate a short feedback for this code.
Don't set the target in the view class. For MVC, the view should not explicitly know about the controller. The view class should have a public property to expose the button and then the controller can update the button to add the target.
Other than that it looks like you understand the point of MVC.
This line does confuse a bit [self.view addSubview:view]; as it appears to be trying to add the view as a subview of itself...
The MVC pattern is a nice thing, but I don't think it is necessary for a program like yours to have that degree of separation. Also the button can be in the view class since it is a part of that pattern along with calculate function.

How do I connect an array of buttons w/i singleton?

My appDelegate, in the method didFinishLaunchingWithOptions I load my view controller then create a singleton:
UIViewController *MainWinVC = [[p3VC alloc] init];
[[self window] setRootViewController:MainWinVC];
ansButSingleton *ansButs = [[ansButSingleton alloc] init];
ansButSingleton.h looks like this:
#import <Foundation/Foundation.h>
#interface ansButSingleton : NSObject {
// View objects:
UIButton *Ans1;
UIButton *Ans2;
UIButton *Ans3;
UIButton *Ans4;
UIButton *Ans5;
UIButton *Ans6;
UIButton *Ans7;
UIButton *Ans8;
// Other objects:
NSArray *ansButs;
}
#property (strong) UIButton *Ans1, *Ans2, *Ans3, *Ans4, *Ans5, *Ans6, *Ans7, *Ans8;
#property (strong) NSArray *ansButs;
+ (ansButSingleton *) ansButsName; // Declare class method
#end
and ansButSingleton.m like this:
#import "ansButSingleton.h"
#implementation ansButSingleton
static ansButSingleton *ansButsName;
#synthesize Ans1, Ans2, Ans3, Ans4, Ans5, Ans6, Ans7, Ans8;
#synthesize ansButs;
//////////////////// instantiate ////////////////////
+ (ansButSingleton *) ansButsName { // class method
#synchronized(self)
{
if (!ansButsName)
ansButsName = [[ansButSingleton alloc] init];
return ansButsName;
}
}
//////////////////// initialize ////////////////////
- (id)init { // class instance method
NSLog(#"Initializing answer buttons");
if (ansButsName) {
return ansButsName;
}
self = [super init];
if(self) {
// First initialze the individual buttons
self.Ans1 = [[UIButton alloc] init];
[Ans1 setTitle:#"" forState:UIControlStateNormal];
self.Ans2 = [[UIButton alloc] init];
[Ans2 setTitle:#"" forState:UIControlStateNormal];
self.Ans3 = [[UIButton alloc] init];
[Ans3 setTitle:#"" forState:UIControlStateNormal];
self.Ans4 = [[UIButton alloc] init];
[Ans4 setTitle:#"" forState:UIControlStateNormal];
self.Ans5 = [[UIButton alloc] init];
[Ans5 setTitle:#"" forState:UIControlStateNormal];
self.Ans6 = [[UIButton alloc] init];
[Ans6 setTitle:#"" forState:UIControlStateNormal];
self.Ans7 = [[UIButton alloc] init];
[Ans7 setTitle:#"" forState:UIControlStateNormal];
self.Ans8 = [[UIButton alloc] init];
[Ans8 setTitle:#"" forState:UIControlStateNormal];
// Make an array containing the objects: this is the objective-C way!
self.ansButs = [[NSArray alloc] initWithObjects: Ans1, Ans2, Ans3, Ans4, Ans5, Ans6, Ans7, Ans8, nil];
}
NSLog(#"Done initializing answer buttons");
return self;
}
#end
This builds and runs fine (it doesn't do much yet). The buttons are visible due to the successful loading of the nib. However, they are not active since I haven't connected them to the code (no IBActions).
Question: How do I connect buttons created this way to the buttons in the nib? If these were simple buttons (not an array of buttons) I would create a method and use IBAction as part of that method declaration. But this case seems a bit different. Or maybe not. If these were labels (which I also need to do later), my reading leads me to believe IBOutletCollection might work, but there is no IBActionCollection that I can see. Expert guidance needed! Thanks.
EDIT ... working with Rob to implement his ideas. My viewLoad method was copied and pasted from yours, but maybe there was something in it I needed to change?
#pragma mark - View lifecycle
- (void)loadView {
NSDictionary *externals = [NSDictionary dictionaryWithObject:[AnswerButtons answerButtons]
forKey:#"answerButtons"];
NSDictionary *nibOptions = [NSDictionary dictionaryWithObject:externals
forKey:UINibExternalObjects];
[self.nibBundle loadNibNamed:self.nibName owner:self options:nibOptions];
[[AnswerButtons answerButtons] buttonsDidLoad];
}
There are a number of ways you could do this. I'd do it by hooking up the singleton's connections in the nib. Here's how.
First, let's fix up the singleton class to match iOS programming conventions and provide the support for wiring up the button connections in the nib:
AnswerButtons.h
#import <Foundation/Foundation.h>
#interface AnswerButtons : NSObject
#property (strong, nonatomic) IBOutlet UIButton *button1, *button2, *button3, *button4, *button5, *button6, *button7, *button8;
#property (strong, nonatomic, readonly) NSArray *buttons;
+ (AnswerButtons *)answerButtons;
- (void)buttonsDidLoad;
#end
AnswerButtons.m
#import "AnswerButtons.h"
#implementation AnswerButtons
#synthesize button1 = _button1;
#synthesize button2 = _button2;
#synthesize button3 = _button3;
#synthesize button4 = _button4;
#synthesize button5 = _button5;
#synthesize button6 = _button6;
#synthesize button7 = _button7;
#synthesize button8 = _button8;
#synthesize buttons = _buttons;
+ (AnswerButtons *)answerButtons {
static AnswerButtons *singleton;
static dispatch_once_t once;
dispatch_once(&once, ^{
singleton = [[AnswerButtons alloc] init];
});
return singleton;
}
- (void)buttonsDidLoad {
_buttons = [[NSArray alloc] initWithObjects:_button1, _button2, _button3, _button4, _button5, _button6, _button7, _button8, nil];
}
#end
Note that we create the singleton in the class method the first time the singleton is requested. Don't do it in application:didFinishLaunchingWithOptions:.
Next, let's hook up the buttons in the nib:
Open the nib for the p3VC class. (You should consider changing this name to start with a capital letter and spell out ViewController or just Controller.)
Drag an “External Object” from the Object Library into the nib.
In the Identity Inspector, set the External Object's custom class to AnswerButtons.
In the Attributes Inspector, set its External Object Identifier to answerButtons.
Control-drag from the Answer Buttons object to each of the eight buttons, connecting the button to the appropriate outlet.
Finally, we need to provide the AnswerButtons singleton to the nib loader when we load the nib. Edit p3VC.m and give it a loadView method:
p3VC.m
- (void)loadView {
NSDictionary *externals = [NSDictionary dictionaryWithObject:[AnswerButtons answerButtons]
forKey:#"answerButtons"];
NSDictionary *nibOptions = [NSDictionary dictionaryWithObject:externals
forKey:UINibExternalObjects];
[self.nibBundle loadNibNamed:self.nibName owner:self options:nibOptions];
[[AnswerButtons answerButtons] buttonsDidLoad];
}
With this approach, you can also create IBAction methods in the AnswerButtons class and use the nib to connect the buttons to those actions.
Since UIButton inherits from UIControl you can use the method:
[yourButton1 addTarget:yourObject action:#selector(yourMethod) forControlEvents:UIControlEventTouchUpInside];
Hook that in the loop where the buttons are created and you are good to go. If you are adding the buttons from interface builder then you need to hook an IBOutlet for each. Example: In your view controller init:
self.Ans1 = [[UIButton alloc] init];
[Ans1 setTitle:#"" forState:UIControlStateNormal];
//set the action
[Ans1 addTarget:self action:#selector(yourMethod) forControlEvents:UIControlEventTouchUpInside];
Another way would be to create the IBAction method for each button and hook that method to the method in the singleton, which in my opinion is much more clear.
Example: in your view controller:
-(IBAction) button1Press:(id)sender{
[yourSingleton button1Press];
}
To connect the buttons to interface builder, you'd have to place "IBOutlet" before the UIButton in each one of your variable declarations.
IBOutlet UIButton * Ans1;
Then in interface builder, you can right click and drag from view controller onto the button and select the right button. Then if you wanted to have each button perform a method, you should declare an IBAction method in your .h file:
-(IBAction)doButtonStuff:(id)sender;
Then to hook up the act to each button in interface builder, go to interface builder and right click and drag from the button to view controller and select what method you want to associate it with. Typically using interface builder is quick and easy but if you want to do some extra behind the scenes stuff, you can use the code whitelion posted.
Also, just a side note, to use less code when setting up your buttons, you can do a for each loop.
for (UIButton * button in ansButs) {
self.button = [[UIButton alloc] init];
[button setTitle:#"" forState:UIControlStateNormal];
}
This is a lot less code!!! You'd have to declare the array before this code and include all of the buttons in it.

initWithFrame doesnt work on my project in IOS 5 but did in IOS 4

I made an program from a tutorial in ios 4 which was a checkbox. I had a friend who is starting to program in xcode for iphone. So, I gave him my codes so he can start. Turns out, he was trying to do the code himself in ios5 following the code I made for IOS4. He kept telling me that his didn't work and that he got a bunch of errors some as follows. So I would open my code and ran it on my updated xcode and it ran fine, no problem what so ever.
The funny thing was when I got to his house and I looked at the code and played around with it. He was right. Trying to do the code from a new project in the new xcode with the new ios, the project would throw all sorts of errors. I posted some in the bottom.
So, my question is this... why is this?
does this have to do with the the way ios5 uses ARC and different properties?
NSObject may not respond to initWithFrame
Instance method - setImageForState not found(return type defaults to "id")
instance method - addTarget:action:forControlEvents not found(return type default to id)
MicheckBox may not respond to initWithFrame
and some more
my code is as follows
have to png one called checkbox_ticked.png and a checkbox_not_ticked.png
micheckbox.h
#import <UIKit/UIKit.h>
#interface MICheckBox : UIButton
{
BOOL isChecked;
}
#property (nonatomic,assign) BOOL isChecked;
-(IBAction) checkBoxClicked;
#end
micheckbox.m
#import "MICheckBox.h"
#implementation MICheckBox
#synthesize isChecked;
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame])
{
[self setImage:[UIImage imageNamed:#"checkbox_not_ticked.png"] forState:UIControlStateNormal];
[self
addTarget:self action:#selector(checkBoxClicked)forControlEvents:UIControlEventTouchUpInside];
}
return self;
}
-(IBAction) checkBoxClicked
{
if(self.isChecked ==NO)
{
self.isChecked =YES;
[self setImage:[UIImage imageNamed:#"checkbox_ticked.png"] forState:UIControlStateNormal];
}
else
{
self.isChecked =NO;
[self setImage:[UIImage imageNamed:#"checkbox_not_ticked.png"]forState:UIControlStateNormal];
}
}
- (void)dealloc
{
[super dealloc];
}
#end
MICheckBoxAppDelegate.h
#import <UIKit/UIKit.h>
#interface MICheckBoxAppDelegate : NSObject <UIApplicationDelegate>
{
UIWindow *window;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#end
MICheckBoxAppDelegate.m
#import "MICheckBoxAppDelegate.h"
#import "MICheckBox.h"
#implementation MICheckBoxAppDelegate
#synthesize window;
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
// Override point for customization after application launch
MICheckBox *checkBox =[[MICheckBox alloc]initWithFrame:CGRectMake(5, 80, 150, 30)];
[checkBox setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[checkBox setTitle:#"Checkbox" forState:UIControlStateNormal];
[window addSubview:checkBox];
[window makeKeyAndVisible];
}
- (void)dealloc
{
[window release];
[super dealloc];
}
#end
I think you forgot to "return self" in the initWithFrame of MICheckBox class.

Calling SEL from parentViewController in iOS

I have a ViewController in which I create a Modal ViewController. I have a SEL value in my modal that I set when it is being instantiated from the parent.
setDateViewController.selectorName = #selector(myMethod:);
In my modal I am trying to call this SEL like:
[[self parentViewController] performSelector:self.selectorName withObject:selectedDate afterDelay:.5];
{selectedDate} is obviously a value from my modal.
I don't get any errors or stack, however, this SEL (method) on my parent is never being called. For some reason I think this should work, but something tells me I'm way off track.
Thanks.
I guess [self parentviewcontroller] is not returning anything.
Try UiviewController* v = [self parentviewcontroller]; and check if is nil. Most probably it should be nil. Else if its was pointing to another object of different class then it would have crashed. Please do one thing. YOu should set bot the object and the methd you need to call. IT will solve any issues if it has any.
setDateViewController.selectorDelegate = self;
setDateViewController.selectorName = #selector(myMethod:);
call like this from parent class. So you can dynamically specify the method and the object you want to call gives more flexibility.
and use,
[selectorDelegate performSelector:self.selectorName withObject:selectedDate afterDelay:.5];
this should solve any issues.
Perhaps you would consider added a delegate protocol to your modal that will allow it to call the method on the parent.
Quick (untested) example:
// MyController.h
#protocol MyControllerDelegate;
#interface MyController : UIViewController
{
id<MyControllerDelegate> delegate;
}
#end
#protocol MyControllerDelegate <NSObject>
- (void)methodToCall:(id)sender;
#end
// MyControler.m
#implementation MyController
- (void) loadView
{
[super loadView];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(20.0f, 20.0f, 50.0f, 30.0f);
[btn setTitle:#"blah" forState:UIControlStateNormal];
[btn addTarget:self.delegate
action:#selector(methodToCall:)
forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
}
#end
// ParentController.h
#interface ParentController : UIViewController<MyControllerDelegate>
{
}
#end
// ParentController.m
#implementation ParentController
- (void)methodToCall:(id)sender
{
NSLog(#"HERE");
}
#end
Just make sure when you are creating your modal controller you set it's delegate to self on the parent:
MyController *controller = [[MyController alloc] init];
controller.delegate = self;
[self presentModalViewController:controller animated:YES];

Objective C: Sending arguments to a method called by a UIButton

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 creation of the UIButton. How would I add in the timer to be sent down to the method? I've tried withObject:timer but it gives me a warning and crashes at runtime.
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:(0.009) target:self selector:#selector(moveStickFig:) userInfo:stickFig repeats:YES];
[stickFig addTarget:self action:#selector(tapFig:andTime:) forControlEvents:UIControlEventTouchUpInside];
This is the method I'm sending it down to:
-(void) tapFig:(id)sender andTime:(NSTimer *)timer
I've also tried [stickFig performSelector:#selector(tapFig:andTime) withObject:nil withObject:timer] after I defined the UIButton, but that also results in a warning and crashes.
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?
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."
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.
First create your support class:
#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
Then change the target:
// 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
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.