I have to pass an object to an button's action... something like
[myButton addTarget:self action:#selector(sendIt:MY_OBJECT) forControlEvents:UIControlEventTouchDown];
I cannot set a variable and use that on the method because I am on a static class.
How do I do that?
You cannot, the signature of an button's action is always*) -(IBAction)methodToCall:(id)sender where sender is your button, or whatever is calling the action.
I cannot set a variable and use that on the method because I am on a static class.
I am not sure what you mean with this.
*) There are a couple of other signatures new on the iPhone compared to the Mac, but none of those allow passing objects either.
The UIButton cannot pass object to event selector. You can use the property tag example:
myButton.tag = SOMEBUTTON_ID;
Also you can cast pointer to you object to NSInteger and assign it to tag property, but this technique does not solve problem of the lifetime of the object and in the future, such code may stop working.
I discovered a way to do that.
You create a class of UIButton and inside the class you declare a public variable that corresponds to the type of object you want to pass.
When you create the button you use that class and store the object inside its property.
then when the button is clicked you retrieve the ID, retrieve the button and the object stored inside it.
Now you have the object...
Related
I have created an IBAction like this: -(IBAction) buttonTapped:(id)sender; and connected it to a UIButton using interface builder, the problem is that I can't do something like NSLog(#"%d",sender.tag); the compiler gives me syntax error that the tag property does not exist in object of type id ... but however when I do something like NSLog(#"%#", sender); the console displays info about the button and its tag ... so the question is: how can I reach the tag property of the UIButton through the sender object ?
Have you tried casting sender? For example:
NSLog(#"%d", ((UIButton *)sender).tag);
You have to cast it, because the compiler does not know the type of object (hence the id type), but the runtime will know.
So, it's similar to :
NSLog(#"%d", [(UIButton*)sender tag]);
Instead of casting, it often makes for cleaner code just to be more specific in your action declaration:
-(IBAction) buttonTapped:(UIButton*)sender;
You can use UIButton, UIControl, UIView or whatever level of specificity you require.
Why does the following code not work?
[Confirm addTarget:self
action:#selector([FunctionsApp Synch_Data:CompIDS])
forControlEvents:UIControlEventTouchUpInside];
given:
FunctionsApp: its other class
Synch_Data:its function in FunctionsApp
CompIDS: its MSmutableArray
FunctionsApp *functions = [[FunctionsApp alloc] init];//of course u need to use your own init method
[Confirm addTarget:functions action:#selector(Synch_Data) forControlEvents:UIControlEventTouchUpInside];
the selector u pass is just the name of the method this is passed to the target who in turn checks if it exists and then calls it. u cant use a mutable array as a selector. since confirm is a button u should use a method with signature - (void)buttonClicked:(id)sender where sender will be the button. and also since the selector is not a class-method you do not call it like this [FunctionsApp buttonClicked:] but instead you use the FunctionsApp object reference as target ( i.e. where the method exists as target).
and please elaborate your question next time and be a bit more concrete in what things are.
Let's take this one thing at a time.
1.
-[UIControl addTarget:action:forControlEvents:] has specific requirements to what the action selector can look like.
It can be one of the following:
- (void)action;
- (void)action:(id)sender;
- (void)action:(id)sender forEvent:(UIEvent *)event;
Normally you'd use the second one.
2.
#selector takes the name of the method (selector) you'd like to have called on the target. You're specifying the return value of a method call. That's the error, you're seeing.
So to call Sync_Data: (which in objective-c would be syncData:) on FunctionsApp you'd write
[Confirm addTarget:FunctionsApp action:#selector(Synch_Data:) forControlEvents:UIControlEventTouchUpInside];
You still can't pass the CompIDS variable as a parameter, though, so I'd suggest rewriting your code, to make it an instance variable, that your action method can access.
Hey guys,
can anyone explain me what (id)sender exactly means? I have seen it in so many actions and I don't know how to set this sender id.
- (IBAction)publishStream:(id)sender {
// do something
}
Furthermore, can you tell me how I can set this sender id in code?
Thanks, Cheers, doonot
'id' is a type -- specifically, it's the type of an untyped pointer to an object. A variable of type 'id' can point to any objective-c object. In the case of an IBAction, it's common to have a single parameter named 'sender' that is the object sending the action. Any type of object can send the action, so the type of the 'sender' parameter is 'id'.
Using that you can re-direct several ui "widgets" to the same handler function. You can then use the "sender" to know which one generated the message.
Well an ID is basically a blank type, so it's whatever type of object that called it, I don't believe that you actually set the sender, it's just the object. So say a UIButton called my IBAction, then whatever the UIButton happens to be will be the sender.
actually, sender is Control which invoke the event.
like,
if if you TouchInside the button and you had attached to your method.
then that button will be sender here.
I have several instances of a UIControl class Foo being instantiated, one instance corresponding to each cell in a UITableView. The Class has:
BOOL selected;
UIImageView *imageView;
UIImage *imageOne;
UIImage *imageTwo;
I've assigned each instance a tag:
foo.tag = indexPath.row;
I would now like to reference the UIImageView.image for a (or several) specific instance(s) by its tag to switch it to the other image.
In my search I've seen things like classes being assigned tags using initWithTag (I assume they're assigning tags)...
SomeClass *someClass = [[SomeClass alloc]initWithTag:1 ...
[someArray addObject: [[SomeClass alloc]initWithTag:2 ...
[someArray addObject: [[SomeClass alloc]initWithTag:3 ...
...but I haven't seen how they are later referenced by that tag.
I have seen a reference to getChildByTag which had promise, but I can't find it in the documentation or examples (maybe not iphone).
Does anyone know how reference the imageView.image within an instance using the instance's tag? (the imageView doesn't have a tag)
Thanks
Let me be a bit more specific. As each instance of Foo is set up in the UITableViewCells I use addTarget
[self addTarget: self action: #selector(switchImage:) forControlEvents: UIControlEventTouchDown];
Then I have this method to switch the images:
- (void) switchImage:(id)sender
{
selected = !selected;
imageView.image = (selected ? imageOne : imageTwo);
// self.tag in here is the indexPath.row from the foo.tag initially assigned
// NSLog(#"switchImage:%#",sender);
}
This works perfectly. I click on the image and the image switches. But in the entire tableView, I only want 1 imageOne all the rest to be imageTwo so I want a way to first turn off all images and then turn on the one. I therefore felt that I could to loop thru all of the instances of Foo using the tag to either somehow directly change the imageView.image or run switchImage in each of the instances to turn off each cell's image.
Lastly, when I look at sender via NSLog, I see that each Foo has a different address so I was wondering if something like allTargets (Foo is a UIControl) would allow me to get to all of the switchImage methods.
I'm pretty deep into this rabbit hole but I'll certainly start over if necessary.
I agree that there are other ways to deal with this, but you could add all your Foo objects to an array or set and iterate through them until you find the one with the tag you want, then access the imageview in the usual way.
If I'm getting you right, you try to access Foo objects (globally) by the tag you assigned to them before. There's no way to do that and it's not what the tag property of UIViews was designed for.
You have to use another way to access your Foo objects. There are uncountable ways of setting up a way to access objects. Since you would usually access them from their data source or view controller, I’d add a dictionary with there. You could also use UITableView's visibleCells property to only change images on cells that are actually displayed.
I feel a bit lost, but how about [UIView viewWithTag:]?
UIView instances have a tag property. You can access them from their superview using:
UIView *view = [superview viewWithTag:n];
I have an Action Sheet popping up and I want to pass a certain argument to a button processing method.
For example:
I have a table and I want to pass to a button processing method row number that was selected in a table.
How can I achieve this?
You would have to set this in your delegate ahead of time. You can then use this value when your delegate receives the button press notification.
If it is an integer argument, put it as the tag property of the action sheet. Otherwise, you can subclass the action sheet and put variables there, or use associative references.
if you want to pass an integer, use UIActionSheet.tag.
if you want to pass a NSString, use UIActionSheet.accessibilityValue.
these are simple and easy. no need to create an instance variable.