Objective C syntax for message passing - iphone

I'm trying following task:
I know we can calla method on button click by using:
[button addTarget:self action:#selector(performModalActionForButton)
forControlEvents:UIControlEventTouchUpInside];
Method is like :
(void) performModalActionForButton:(NSString *)str
{
}
I want to send a string on button click to one method. How can I achieve this?
Thanks

there are two small mistakes in your code..
if you use #selector and want to choose a function with a parameter you have do add a : ... so it is #selector(performModalActionForButton:)
the object passed to the function always the sender of the message .. so the function would be:
- (void) performModalActionForButton:(UIButton *)button
{
}
In the function you can check the text on the button then... or the tag or whatever you want.

You have the button click trigger an action method that then sends the message whose argument is the string you want to send:
[button addTarget:self action:#selector(performModalActionForButton:)
forControlEvents:UIControlEventTouchUpInside];
- (IBAction)performModalActionForButton:(id)sender
{
NSString *string = /* get the string you want to send */;
[obj doSomethingWithString:string];
}

Related

UIButton action with multiple argument [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Objective C: Sending arguments to a method called by a UIButton
i have a problem with uibutton action. I want send argument when the button clicked. i saw some examples that work with tag prop. and the class is id sender. but i dont want to fixed it. the action goes to my own manager. how can i do ?
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton addTarget:self
action:#selector(goToSubViewManager:)
forControlEvents:UIControlEventTouchUpInside];
here is the gotosubviewmng
- (void)goToSubViewManager:(ViewType*)vTipi
{
}
you should only use - (void)goToSubViewManager:(id)sender. or - (void)goToSubViewManager
so here are 2 ways to solve your problem.
you can use variables or property.
- (void)yourMethod
{
//your code
_vTipi = yourVTipi;
}
- (void)goToSubViewManager
{
//here you can use _vTipi;
}
you can add a Category for the UIButton , to add an id type property(such as #property(nonatomic) vTipi).faking instance variables for UIButton.(how to do you can look at this : http://oleb.net/blog/2011/05/faking-ivars-in-objc-categories-with-associative-references/) Then you can use like this:
- (void)goToSubViewManager:(id)sender
{
//you can user ((UIButton *)sender).vTipi
}
Use can use tag property of the button. And then can use that object by comparing the tag assigned.
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton addTarget:self
action:#selector(goToSubViewManager:)
forControlEvents:UIControlEventTouchUpInside];
rightButton.tag=1;
//
then in the call back you can compare it as
- (void)goToSubViewManager:(id)sender
{
if(sender.tag==1){
// you can use an array of that object(if multiple), then apply your logic
}
}

Objective-C #Selector(methodWithArguments) [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Arguments in #selector
This is probably a really simple question, but I need a really good answer...
Using the following code I can call a method when a button is clicked...
[pushButton addTarget:self action:#selector(pushOrPull:andVI:) forControlEvents:UIControlEventTouchUpInside];
[pullButton addTarget:self action:#selector(pushOrPull:andVI:) forControlEvents:UIControlEventTouchUpInside];
The method is below...
-(void) pushOrPull: (int)pushPull andVI: (NSString *) videoId {
}
I want the buttons to be able to supply arguments to that method, but when I try this...
[pushButton addTarget:self action:#selector(pushOrPull:2 andVI:#"someVID") forControlEvents:UIControlEventTouchUpInside];
[pullButton addTarget:self action:#selector(pushOrPull:1 andVI:#"someVID") forControlEvents:UIControlEventTouchUpInside];
Xcode gives me two errors: "expected )"
How can I supply these two arguments to the method when my buttons get tapped?
What you could do is just have a method in the middle.
[pushButton addTarget:self action:#selector(runMyMethod) forControlEvents:UIControlEventTouchUpInside];
pushButton.tag =0;
[pullButton addTarget:self action:#selector(runMyMethod) forControlEvents:UIControlEventTouchUpInside];
pullbutton.tag =1;
-(void) runMyMethod:(id)sender {
if(sender.tag ==0)
{
[self pushOrPull:1 andVI:#"someVID"];
}
else if (sender.tag ==1)
{
[self pushOrPull:2 andVI:#"someVID"];
}
}
-(void) pushOrPull: (int)pushPull andVI: (NSString *) videoId {
}
Unfortunately, you can't. Buttons only "know how" to send themselves as the first argument. The best bet is to have the buttons "belong" to some view controller (to which they send their events) which can interpret the button press, and then call a delegate method elsewhere with as many arguments as you need.
To answer a related question, a "selector" never carries actual arguments, but it does carry one colon per argument: #selector(aMethodWithThis:andThat:)
This is a bit better:
// set up an NSMutableDictionary, videoIDsForButtons as an iVar or property
[pushButton addTarget:self action:#selector(buttonWasPressed:) forControlEvents:UIControlEventTouchUpInside];
[videoIDsForButtons setObject: #"someVID" forKey: pushButton];
[pullButton addTarget:self action:#selector(buttonWasPressed:) forControlEvents:UIControlEventTouchUpInside];
[videoIDsForButtons setObject: #"someVID" forKey: pullButton];
- (void)buttonWasPressed:(id)sender
{
if (sender == pushButton)
{
[self pushOrPull: 2 andVI: [videoIDsForButtons objectForKey: sender]];
}
else // assume pullButton
{
[self pushOrPull: 1 andVI: [videoIDsForButtons objectForKey: sender]];
}
}
This is because selectors don't take arguments, only method calls do. And when a button is pressed, it supplies itself as the only argument (sender). You should have a whole separate responder method that looks at sender and determines the appropriate recourse.
unfortunately the -addTarget:action:forControlEvents: can call back you via the following method with the next parameters only:
-(IBAction)selector:(id)sender forEvent:(UIEvent *)event;
so, you should check inside this method which object fired the event (sender), and after it, still inside this method you can call your own -pushOrPull:andVI: method with the desired parameters, or you can set two different callback methods as well and then you won't have to check the sender parameter, just call your -pushOrPull:andVI: like this:
{
// ...
[pushButton addTarget:self action:#selector(pushButtonTouchedUpInside:) forControlEvents:UIControlEventTouchUpInside];
[pullButton addTarget:self action:#selector(pullButtonTouchedUpInside:) forControlEvents:UIControlEventTouchUpInside];
// ...
}
- (IBAction)pushButtonTouchedUpInside:(id)sender {
[self pushOrPull:2 andVI:#"someVID"];
}
- (IBAction)pullButtonTouchedUpInside:(id)sender {
[self pushOrPull:1 andVI:#"someVID"];
}

Objective C Syntax: addTarget on UISwipeGestureRecognizer

I'm currently working on an app where the user has the option to either swipe through data, or use a button to go through the data. I'm having trouble understanding how to combine two bits of code.
Here is the code I'm using for swiping:
- (void)swipeRight:(UISwipeGestureRecognizer*)recognizer
{
if ([questions hasPrevQuestion] == YES) {
[self vorige:nil];
}
}
(the [self vorige:nil]; is calling the method for the button, so the swiping and the button have the same behavior)
and I need to somehow incorporate this code which applies to the button:
-(void)animationDidEndOnAnswer {
[vorigeButton addTarget:self action:#selector(newQuestion:) forControlEvents:UIControlEventTouchUpInside];
}
I think it's pretty simple, but I just cannot for the life of me figure out how to call the swiping method place of the button here...I'm thinking it's simple because I found this example in the UIGestureRecognizer class reference:
- (void)addTarget:(id)target action:(SEL)action
but being new to objective-c, I don't really know what to do with this. any help is very appreciated.
- (void)addTarget:(id)target action:(SEL)action is the code equivalent of binding a button action to a method like you do when you ctrl-drag from a button to an IBAction in Interface Builder.
So if your method is called vorige: and you want it to be called when the button is tapped, you would say:
[vorigeButton addTarget:self action:#selector(vorige:) forControlEvents:UIControlEventTouchUpInside];
But I don't know why you would want to do that as a result of an animation - you normally would set the button action once when the view is loaded, not change it during an animation.
Nick's solution is good.
if you want to call the same method for the swiping & the tap on your button, you can tweak your swipeRight like this:
- (void)goThrougtData:(id)sender
{
if( [sender isKindOfClass:[UISwipeGestureRecognizer class]] ) {
// swipe specific code
}
else if( [sender isKindOfClass:[UIButton class]] ) {
// tap specific code
}
if ([questions hasPrevQuestion] == YES) {
[self vorige:nil];
}
}
and in your init method, you add
[mySwipeRecognizer addTarget:self action:#selector(vorige:)];
[vorigeButton addTarget:self action:#selector(vorige:) forControlEvents:UIControlEventTouchUpInside];

What does a UISegmentedControl return to its action on UIControlEventValueChanged?

So, I have a UISegmentedControl with:
[control addTarget:self action:#selector(myAction) forControlEvents:UIControlEventValueChanged];
Just wondering how I would find out what segment has been selected (so I can do the appropriate action). I know its something like:
#selector(myAction:) but what gets sent? ie: when I define my method what do I have to define?
Thank you.
get the selected item... second part of question
-(IBAction) myAction:(id)sender{
NSLog(#"myAction",nil);
UISegmentedControl * control = sender;
int selectedIndex = [control selectedSegmentIndex];
}
- (IBAction)myAction:(id)selector;
selector is an UISegmentedControl object. Thus you may differ two UISegmentedControl's if you bind one action to both.
There is also easier way:
-(IBAction) myAction:(UISegmentedControl*)control {
NSLog(#"selected index %d", control.selectedSegmentIndex);
}

cocoa UIImageView addTarget with extra parameter

With a loop I add UIImageView to a UIScrollView i need to add an extra parameter addTarget so when i click i can log the index.
[imageButton addTarget:self action:#selector(buttonPushed:)
forControlEvents:UIControlEventTouchUpInside];
-(IBaction) buttonPushed: (int) index
{
NSLog(#"%d",index);
}
How do i achieve this?
When you add a target, the method being call can either have no arguments (e.g. buttonPushed) or have one (buttonPushed:) which is the control sending the event (in this case your button). If you want an index, or any other value, you need to set it on the button sending the event. For example, when you setup the buttons:
myButtons = [NSArray arrayWithObjects:myFirstButton, mySecondButton, nil];
[myFirstButton addTarget:self action:#selector(buttonPushed:)
forControlEvents:UIControlEventTouchUpInside];
[mySecondButton addTarget:self action:#selector(buttonPushed:)
forControlEvents:UIControlEventTouchUpInside];
and implement your action as
- (IBaction)buttonPushed:(UIButton *)button
{
NSLog(#"%d",[myButtons indexOfObject:button]);
}
Use the tag property of the button