I have an UIButton that is subview on an UIView. When the button is pressed, my app is supposed to pass a captured image into a function called by the #selector. However, my research shows me that I am not able to pass anything to the function with the selector of the UIButton. How can I go around this?
[hangButton addTarget:self
action:#selector(faceDetector: the image I want to pass in)
forControlEvents:UIControlEventTouchUpInside];
You should trigger your events within a handleButton press method. You don't preset arguments, buttonPress selectors pass one argument, the button that is sending the event.
[hangButton addTarget:self
action:#selector(handleButtonPress:)
forControlEvents:UIControlEventTouchUpInside];
- (void) handleButtonPress:(id)sender {
UIImage * imageToFaceDetect = // get your image
[self faceDetector:imageToFaceDetect];
}
Related
I have made a custom cell.In each custom cell there are many button like 3 to 4 i want add tap gesture for each button inside that cell.So that i can uniquely identify which cell's button was clicked.I have searched a lot but didn't find any good solution.
Please tell.
you want to access the button you can directly access, no need of Gesture
do like
[yourButton1 addTarget:self action:#selector(selectButtonPressed1:) forControlEvents:UIControlEventTouchUpInside];
yourButton1.tag=indexPath.row;
[yourButton2 addTarget:self action:#selector(selectButtonPressed2:) forControlEvents:UIControlEventTouchUpInside];
yourButton2.tag=indexPath.row;
[yourButton3 addTarget:self action:#selector(selectButtonPressed3:) forControlEvents:UIControlEventTouchUpInside];
yourButton3.tag=indexPath.row;
[yourButton4 addTarget:self action:#selector(selectButtonPressed4:) forControlEvents:UIControlEventTouchUpInside];
yourButton4.tag=indexPath.row;
Method - 1
-(void)selectButtonPressed1:(UIButton*)sender
{
NSLog(#"selcted button1");
}
Method - 2
-(void)selectButtonPressed2:(UIButton*)sender
{
NSLog(#"selcted button2");
}
Method - 3
-(void)selectButtonPressed3:(UIButton*)sender
{
NSLog(#"selcted button3");
}
Method - 4
-(void)selectButtonPressed4:(UIButton*)sender
{
NSLog(#"selcted button4");
}
Lets say you have n number of buttons. And you have one butotn action method:
YOu need to connect this method to all of your n buttons (touch up inside), so that whenever you press a button, this method will get hit.
You can either give tag values for your buttons or you can recognise them by thier title
-(IBAction) nButtonActions:(id)sender{
if([[sender titleLabel] isEqualtoString:#"your button-1 title"]){
//call your method for button -1
}
//or you can do the same using sender.tag
}
use restoration identifier.
button.restorationIdentifier = #"Cell Number _ button tag";
for example
button.restorationIdentifier = [NSString stringWithFormat:#"%#", indexPath.row];
NSString* rowIndexStr = ((UIButton*)sender).restorationIdentifier;
I have a UIButton. I bound a target as follows.
[button addTarget:self action:#selector(myFunction)
forControlEvents:UIControlEventTouchUpInside];
When i click my Button multiple times quickly it invoke the target function multiple times.
On Tapping button i present a new View controller.
when i click 3 times quickly then my new view controller is shown 3 times.
This is something stupid. Whats the point of triggering the function again once the View has been shifted to a new View controller. Why the Hell Apple do such stupid things ?
Any Help please?
First of all its not apple bugs. It should be handle manually. So follow these step
First make your global instance of your button then do this
.h file
#property (weak, nonatomic) IBOutlet UIButton *btn;
.m file
- (IBAction)myFunction:(id)sender
{
self.btn.userInteractionEnabled = NO;
}
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.btn.userInteractionEnabled = YES;
}
Take one global bool flag like "isItDone" or it declare in singleton class.
in "myFunction" set it as false
which View controller you push on that function in that class's "ViewDidAppear" method set as true.
it will help you.
I have same problem and it is good solution for that to manage it using one global variable.
I think this will help you.
Change your calling function like this
- (IBAction)myFunction:(id)sender
{
UIButton *button = (UIButton*)sender;
button.userInteractionEnabled = NO;
}
and call your function like this
[button addTarget:self action:#selector(myFunction:)
forControlEvents:UIControlEventTouchUpInside];
if you want to store the selection incase you came back to the view controller then only you need to keep a boolean flag to store if its clicked once or not.
Set the IBOutlet to your button, in the viewWillAppear method write,
button.userInteractionEnabled = YES;
and when you click on the button set,
button.userInteractionEnabled = NO;
I add UIButton programmatically (self.button is my property UIButton):
self.button = [[UIButton alloc] initWithFrame:CGRectMake(139, 366, 42, 34)];
[self.button addTarget:self action:#selector(buttonPressed:completion:) forControlEvents:UIControlEventTouchUpInside];
I call programmatically to the button target and also I want the framework to invoke the target when the user push the button.
The target selector is:
-(void)buttonPressed:(UIButton*)sender completion:(void (^)())completionBlock;
The second argument is a block.
When I try to introspection/invoke the block I get an exception EXC_BAD_ACCESS (code=2, address=0x0)
I know that I try to invoke UITouchesEvent because of the framework target action.
How can I make custom target with completion block?
You can't pass a completion block there, but you can make something like this:
self.button = [[UIButton alloc] initWithFrame:CGRectMake(139, 366, 42, 34)];
[self.button addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
-(void)buttonPressed:(UIButton*)sender {
[self buttonPressed:sender completion:^{
//something
}];
}
-(void)buttonPressed:(UIButton*)sender completion:(void (^)())completionBlock {
//do something
//invoke block
completionBlock();
}
You can't. For the button action, system expect to have a single parameter and that too is the sender(Invoker of the action method) ie the UIButton instance itself. If you want to do anything with a second argument i would suggest you to have a wrapper some thing like
-(void)buttonPressed:(UIButton*)sender
{
[self customMethodWithcompletion:^{
}];
}
Inside the customMethodWithcompletion you can perform your operations.
A target-action listener for UIKit must have one of the following three signatures:
- (void)action
- (void)action:(id)sender
- (void)action:(id)sender forEvent:(UIEvent *)event
If there is a first parameter, the "sender" control (the control that you are listening to actions for) will be passed to it. If there is furthermore a second parameter, the UIEvent object will be passed to it. You don't have any control over what is passed to the method.
There are many third-party libraries that implement a Block-based API for UIControls that you can find on the Internet. Essentially what they do is attach the completion block as an associative object to the control, and retrieve it in the handling method.
I am trying to add a button to a view programmatically and i am using the following code:
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setTitle:#"Click Me" forState:UIControlStateNormal];
[button addTarget:self action:#selector(click:) forControlEvents:UIControlEventTouchDown];
[button setFrame:CGRectMake(50, 20, 80, 70)];
[self addButton:button];
according to me code looks right but i am getting error "Unknown action click"
addbutton and click is the method of the same class
and i am adding the buttons in my constructor
what's the problem with the click method? is there any syntax error!
Your problem is that you have a method named click but your are telling your button that the method is named click:. Notice the difference (the colon).
Change the #selector to #seletor(click) so it matches the actual method name.
Another option is to leave the #selector as-is but update your click method to click::
- (void)click:(UIButton *)button {
// button was tapped - do something
}
A sample how to add a action to a button ....
UIButton *button = [UIButton buttonWithTypeRoundRect];
[button addTarget:self action:#selector(myMethod) forControlEvents:UIControlEventTouchUpInside];
button.frame = CGRectMake(10,10,100,50);
//Do some more Configuration of the button like title.. Look at UIButton Class Reference
[self.view addSubview:button];
SomeTimes you see a small colon(:) after the method name in the selector something like this #selector(myMethod:)
which means this method takes some argument. the colon plays no role in the name of the method. if you are not sending any argument to the function then don't put colon after the name of the function.....
In addtarget option you can see that self is specified because self contains myMethod function. Here you are supposed to specify the reference of that object which contains your Method.
change
- (void)click:(id)sender{ NSLog(#"Button Clicked"); }
or change action click: to click
[button addTarget:self action:#selector(click) forControlEvents:UIControlEventTouchUpInside];
hi just simply try this -(void)click { // do what ever } i.e just remove colon in #selector(click:) hope it will work
essentially I'm deleting pictures inside of an app.. everything is coded etc.. etc.. so when the user holds the UIButton the image is swapped and has the X over it. Click again and image is deleted from the Doc Directory and DB. So it only made sense to add an alertview before deletion.. problem is that the methods I'm using use (UIButton*)sender as a parameter. I need to pass that parameter to the next method to property delete from the screen.
Is there a relatively simple way to do this..
this is the function that calls the deletion.. the function that would initiate the alertview is also returns a void and takes the same UIButton.
-(void)action:(UIButton*)sender {
if (edit == true)
{
[sender removeFromSuperview];
[[scrollView viewWithTag:[sender tag]] removeFromSuperview];
[self deleteFromDoc:sender];
edit = false;
stop = false;
NSLog(#"remove");
}
}
Change your method to
-(void)action:(UIView *)sender
Assign the tag of the uibutton to the alertview, then in didClickButtonWithIndex: call your action: method passing in the alertView as sender.