How do I determine which control fired an event? - iphone

I have the Value Changed event of two UISliders (both of which have referencing outlets) wired up to the following method:
-(IBAction) sliderMoved:(id) sender {}
How can I determine which slider was moved so that I can get its value and update the corresponding label? Or would it be simpler to have two separate events, one for each slider? The second option seems like unnecessary replication to me.
Cheers,
Dan

It's going to be the sender variable. Just do all your work with it.
It's legal to strongly type it, by the way. So if you know you're only going to deal with UISlider objects, you can do -(IBAction)someAction:(UISlider*)slider {}.

You can use [sender tag] to get the tag of the slider if you have set that up. Assign the tag when you create the sliders or in interface builder.
-(IBAction) sliderMoved:(UISlider*)sender {
switch ( [sender tag] ) {
case kMyOneSlider: ... break;
case kMyOtherSlider: ... break;
}
}
You can use == with the outlet members for each slider:
-(IBAction) sliderMoved:(UISlider*)sender {
if ( sender == mOneSlider ) ...;
if ( sender == mOtherSlider ) ...;
}
Or you can set up different actions for each slider. I generally share one action method if there is some common code in the handlers.

Related

Linking multiple buttons to one method with different jobs

I have a huge crazy scene in my story board that has 36 different buttons, and each one means something different when clicked on. I really don't want to go about creating 36 different methods, so how could I reference a button title or button name in a method that is called when one of the 36 buttons is pushed.
This is probably a simple question, but I'm new to iOS and Objective C...
Thanks!
You can create a single method, like so:
- (IBAction)buttonTapped:(id)sender{
// The button that was tapped is called "sender"
// This will log out the title of the button
//NSLog(#"Button: %#", sender.titleLabel.text);
//Edit: You need a cast in the above line of code:
NSLog(#"Button: %#", ((UIButton *)sender).titleLabel.text);
}
Then, you can use Interface Builder to connect to all of the buttons. You can have some sort of if/else logic to test which button was tapped.
You can check the titleLabel property, or you can assign an IBOutlet to each button and check for that.
For example:
if([sender isEqual:buttonOutlet1]){
//If this button is attached to buttonOutlet1
//do something
}
Alternatively, you can simply use the label of each button, not worrying about outlets.
A third option would be to generate and lay out the buttons in code, and then access them as elements of an array of buttons.
A fourth option would be to add tags to the buttons and check for the button's tag in your function.
Give each button a unique tag value. in the IBAction, sender.tag tells you which button was tapped.
The IBAction routine you set up to handle the button presses has a sender parameter. Examine that to decide.
-(IBAction) buttonPress: (id) sender {
UIButton *pressedButton = (UIButton *)sender;
NSString *buttonTitle = [pressedButton currentTitle];
if ([buttonTitle isEqualToString: #"SomeTitle"]) {
//do work for that button.
}
}
You can use a variety of NSString methods to compare or filter which button was pressed and handle it through if's or switches.
That's quite simple, but since you're new, here's an answer.
(According to Stanford cs193p course, 2010-2011 fall (that's what they did with the calculator app)) make a method that receives an argument, which is the UIButton.
for example:
- (IBAction) someMethodThatDoesSomething:(UIButton *)sender;
Then make if statements according to the sender.titleLabel.text
I don't know if there are any other solutions. Hope this helps!
-(IBAction)myButtonAction:(id)sender {
if ([sender tag] == 0) {
// do something here
}
if ([sender tag] == 1) {
// Do some think here
}
}
// in Other words
-(IBAction)myButtonAction:(id)sender {
NSLog(#"Button Tag is : %i",[sender tag]);
switch ([sender tag]) {
case 0:
// Do some think here
break;
case 1:
// Do some think here
break;
default:
NSLog(#"Default Message here");
break;
}

Custom iphone keyboard

I want to make a custom keyboard for my app and want to use the send button to set a character.
If I name all my buttons e.g. *a, *b, *c, *d etc. will it work to have one IBAction which takes the sender, grabs the name e.g. *a > a ? If so, how is this done.
Also, can a button be named as follows *0, *1, *2 rather than *zero, *one, *two?
Thanks
No, variables don't really work that way. You are confusing the object itself with the name of the variable that points to it. When your IBaction is passed the UIButton object, it's not passing a variable name along with it, your method defines the variable that references it as sender. And no, variable names cannot start with a digit in Objective C.
A common approach to differentiating between buttons in this way is to set the tag and branch on that. Alternatively, you can access the title - it depends on exactly what you are doing.
If you mean you want to point multiple UIButtons at the same IBAction and then extract the textual label of the button, you can simply use the currentTitle property of the sender.
For example:
- (IBAction)padButtonClicked:(id)sender {
NSLog(#"Button pressed: %#", [sender currentTitle]);
}
You are better off using tags for your buttons.
- (IBAction)buttonTapped:(id)sender {
NSLog(#"Button pressed: %i", sender.tag);
switch (sender.tag) {
case 0:
/* Button A Pressed */
break;
case 1:
/* Button B Pressed */
break;
/* and so forth... */
}
}
You will need to set the tags either in Interface Builder, or programmatically.

Assigning same action to multiple buttons at once

can I assign same action to multiple buttons in the Interface Builder once they are all selected by one connection?
This problem is discussed in numerous threads but it isn't always just laid out simply. The easiest route is to create a function such as the one below. It takes the sender, in this case a UIButton, and gets the tag. You can then run whatever code you want based on that.
- (IBAction) buttonClick: (id) sender {
UIButton *button = (UIButton *)sender;
int row = button.tag;
NSLog(#"Button clicked: %i", row);
if (row == 1 ) {
// do something
}
}
In Interface Builder, attach the button to the function, and then use the Attributes Inspector to set the Tag value for each button, giving each one a different integer value.

How to know or retrieve the sender id

I have the following method
-(IBAction)back:(id)sender {
}
and would like to be able to know the sender id.
e.g. if there are multiple buttons linked to this method, I would like to know which button was pressed.
Simply use the tag property, inherited from UIView, which is a NSInteger, in a switch statement, or using if conditions.
The tag property can be set in your code, or through InterfaceBuilder.
[sender tag]
I don't know what you mean by "id" (the "sender" is an id, effectively an NSObject *), but you could use tags. You have to set the tag beforehand in Interface Builder or programmatically.
If you have set up IBOutlets for the buttons in your interface then you can simply compare the sender to those.
That is in your interface definition if you have
...
(IBOutlet) UIButton *button1;
(IBOutlet) UIButton *button2;
...
and in your implementation you have:
- (IBAction) buttonPressed: (id) sender
{
if (sender == button1) {
....
}
else if (sender == button2) {
...
}
}
Personally, I'd prefer to use different action methods for each button and then they can all call a common routine for the things that are common. However, for simple projects the above will work.
-J
Set the tag property of each button to a unique integer (either in IB or programmatically) and switch on it inside your action method.

How to add (id) sender to the following -(IBAction)?

How do you add a (id) sender to the following code?
- (IBAction) gobutton: (UIButton *) button5 {
Everything I try fails, any help would be appreciated. Thanks.
EDIT: I need to keep the (UIButton *) button 5 reference in the (IBAction)
If I recall correctly, and if you are using this in the way I think you are,
- (IBAction) gobutton: (id) sender {
if(sender == button5)
//do something...
else
//do something else...
}
Assuming that you specified button5 as a parameter to indicate that this executes in response to button5 being pressed.
Ok, first.... IBAction doesn't really mean anything special except to Interface Builder. Basically:
#define IBAction void
So whenever you see IBAction, think "void". The only reason it's there is as a flag to tell Interface Builder that a method is a valid method to connect control actions to. The Objective-C compiler doesn't need to know about it and so it's defined to void since all "action" methods return void.
Second, action methods also have one argument which could be an object of any number of types. Because of this, action methods are supposed to use type id as the type for their argument. That way they can be passed a pointer to any Objective-C object without causing the compiler to generate a type checking error.
So usually actions should work something like this:
- (IBAction)myAction:(id)sender {
if (sender == self.someButton) {
UIButton *button = (UIButton *)sender;
...
return;
} else if (sender == self.someControl) {
UIControl *control = (UIControl *)sender;
...
return;
}
}
In other words, an id is almost like an untyped pointer like a void * is routinely used in C when some function needs to take a pointer to something of unknown type. sender could be different types of control, so something generic like id is used then sender is cast to something more specific once the code knows what it is.
Anyway, there is absolutely no reason to define something as having a return type of IBAction unless you are going to use that method as a target action in Interface Builder. Having an IBAction in your app delegate seems kind of unusual....
It's not clear what you are trying to do but most actions look like:
- (IBAction) gobutton: (id)sender;
The first parameter to an action is always the sender (you can specify the type and name as appropriate).
If a method is the action for a button, then the first parameter will be the button. If that method is the action for several buttons, then the first parameter will allow you to determine which button was tapped (as Leper describes).
What problem are you actually trying to solve?
There are techniques for passing information to the action method. For example, if you have a button that appears on a table view cell and performs the same action for every cell, then in the action method, you would want to be able to determine which cell's button was tapped.
How can I get the id of the sender before the user touches the control?
Found it! Set a tag and the use viewWithTag.
Can you create a simple structure that contains both the UIButton and the sender and use that?
struct myObject
{
UIButton* button5;
id sender;
}
...or, you could create your own NSObject (probably more cocoa-y):
#instance myObject : NSObject
{
...
}