How to pass argument to action in UIGestureRecognizer initWithTarget action - selector

I am using the code below
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(processTap)];
- (void) processTap
{
//do something
}
But I need to send a data to processTap function. Is there anyway to do this?

Example:
UIImageView *myPhoto = [[UIImageView alloc] initWithImage: [UIImage imageNamed:#"tab-me-plese.png"]];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(processTap:)];
[myPhoto setTag:1]; //set tag value
[myPhoto addGestureRecognizer:tap];
[myPhoto setUserInteractionEnabled:YES];
- (void)processTap:(UIGestureRecognizer *)sender
{
NSLog(#"tabbed!!");
NSLog(#"%d", sender.view.tag);
}

There's a good answer to a similar question at iOS - UITapGestureRecognizer - Selector with Arguments, but if you want to pass data that you don't want to attach to the view, I recommend creating a second function that has access to the data you need. For example:
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(passDataToProcessTap)];
- (void)passDataToProcessTap {
[self processTapWithArgument:self.infoToPass];
// Another option is to use a static variable,
// Or if it's not dynamic data, you can just hard code it
}
- (void) processTapWithArgument:(id)argument {
//do something
}

Related

Detect The Users Taps

I want to use tap gesture recognizer for detecting the user taps .i don't have much knowledge about this .Can anyone please help me for this .Tap Gesture .
I want to set the maximum count and i want to detect the user taps count if it is equal i want to perform some operation .Please help me to do this .
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTapGesture:)];
tapGesture.numberOfTapsRequired = 1;
[self.imageforcapture addGestureRecognizer:tapGesture];
The above code is simple example of tea gesture recognizer .
Thanks in advance !!!!
Init Method :
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTapGesture:)];
tapGesture.numberOfTapsRequired = 1;
[self.imageforcapture addGestureRecognizer:tapGesture];
Handle Method :
- (void)handleTapGesture:(UITapGestureRecognizer*)sender {
i=i+1;
if(i==10)
{
//Prforme task here
}
}
Declare i as global variable
Use this:
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(foundTap:)];
tapRecognizer.numberOfTapsRequired = 1;
tapRecognizer.numberOfTouchesRequired = 1;
[self.view addGestureRecognizer:tapRecognizer];
-(void)foundTap:(UITapGestureRecognizer *)recognizer
{
// Your code goes here
}
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTapGesture:)];
tapGesture.numberOfTapsRequired = 1;
self.imageforcapture.userInteractionEnabled = YES;
[self.imageforcapture addGestureRecognizer:tapGesture];
First, you need to allow imageView to receive touches by adding line above.
Define global variable i.
#property NSInteger i;
in viewDidLoad set the value of i to 0
self.i = 0;
After that you need to handle that global i variable that will track taps.
- (void)handleTapGesture:(UITapGestureRecognizer*)sender {
self.i++;
if (self.i == 10) {
//Perform your expected behaviour
}
}

[UITapGestureRecognizer tag]: unrecognized selector sent to instance

I am having a series of imageview arranged, and assigning a TapView recognizer to it
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(action:)];
[tapRecognizer setNumberOfTouchesRequired:1];
[tapRecognizer setDelegate:self];
imageView.userInteractionEnabled = YES;
[imageView addGestureRecognizer:tapRecognizer];
and I have defined the selector as:
-(void) action:(id)sender
{
NSLog(#"TESTING TAP");
NSLog (#"%d",[sender tag]);
}
This is getting Crashed and i am getting Error message as:-
[UITapGestureRecognizer tag]: unrecognized selector sent to instance 0x145d0210
You can use this..
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(action:)];
[tapRecognizer setNumberOfTouchesRequired:1];
[tapRecognizer setDelegate:self];
imageView.userInteractionEnabled = YES;
imageView.tag = 1111;
[imageView addGestureRecognizer:tapRecognizer];
And in action try this..
-(void) action:(id)sender
{
NSLog(#"TESTING TAP");
UITapGestureRecognizer *tapRecognizer = (UITapGestureRecognizer *)sender;
NSLog (#"%d",[tapRecognizer.view tag]);
}
Explaination:
UITapGestureRecognizer has not property like tag. but it has property view, from this property you can access the view with which UITapGestureRecognizer was attached.
Hope it will help you
Just Change your Selector Method with the following..and it will work
tapgesture will have the whole view which is tapped.. and then you can get the tag property from it as i have stated in following
-(void)action:(UITapGestureRecognizer *)tapGesture{
NSLog(#"TESTING TAP");
NSLog (#"%d",tapGesture.view.tag);
}
Neither UITapGestureRecognizer nor UIGestureRecognizer declares a property or method called tag.
You can't use it. That's why you're getting the error.
On a related note. I really don't like using tag in general. There is always a better way to do what you're doing without using tag.
Swift equivalent of the accepted answer:
//use this to set up your tap gesture
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.reactToTap(sender:)))
imageView.tag = 33
imageView.isUserInteractionEnabled = true
imageView.addGestureRecognizer(tapGesture)
This is the function which gets triggered by the tap:
#objc private func reactToTap(sender: UITapGestureRecognizer) {
print("ImageView tag: ", sender.view?.tag ?? 0) //"ImageView tag: 33"
}
You cannot get tag property of UITapGestureRecognizer rather you have to get of its view's property,
You can try,
-(void)action:(id)sender
{
NSLog(#"TESTING TAP");
NSLog (#"%d",[[sender view]tag]);
}

NSString and UITapGestureRecognizer as method arguments

I am wondering how to use a NSString and a UITapGestureRecoginzer as method arguments in Xcode.
Now I have this code:
-(void)setLanguage:(NSString *)language :(UITapGestureRecognizer *)gesture {
gesture.view.alpha = 0.8;
[[NSUserDefaults standardUserDefaults] setValue:language forKey:#"GameLanguage"];
}
and this for theUITapGestureRecognizer:
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(setLanguage:#"en":tap)];
[ENImage addGestureRecognizer:tap];
When I try it this way I only get errors. How can I solve this?
The action of UITapGestureRecognizer's can only take one parameter, which is itself or no parameter. Please review this question.
I find your "language" is a constant NSString "en", why not try this:
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped:)];
[ENImage addGestureRecognizer:tap];
In your -tapped:
- (void)tapped:(UITapGestureRecognizer *)gesture
{
gesture.view.alpha = 0.8;
// Or you can call your custom method like [self setLanguage:#"en"]
[[NSUserDefaults standardUserDefaults] setValue:#"en" forKey:#"GameLanguage"];
}
You are missing the name of the second parameter
-(void) setLanguage:(NSString *)language withGesture:(UITapGestureRecognizer *)gesture is the correct signature
try this:
replace your gesture allocation coding with following lines
NSString *strLanguage = #"en";
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(setLanguage:strLanguage:)];
[ENImage addGestureRecognizer:tap];
and replace your setLanguage method with following code
-(void)setLanguage : (NSString *) language : (id)sender {
UITapGestureRecognizer *gesture = (UITapGestureRecognizer *) sender;
gesture.view.alpha = 0.8;
[[NSUserDefaults standardUserDefaults] setValue:language forKey:#"GameLanguage"];
}
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(setLanguage:#"en":tap)]
When using the #selector() syntax, you cannot pass parameters. #selector is a macro that will search across table at runtime for a method matching the given signature, so passing argument within the parentheses is not such a good idea :-)
You should use
#selector(setLanguage::)
Then, becuase that is how UIGesture Recognizers are made, the method you provide as action MUST accept 0 or 1 parameter, not more! And if your method accept 1 parameter, AUTOMATICLY it will be the triggered gesture recognizer that will be passed.
So, in your situation, like liuyaodong adviced, change your tapHandling method to something like
- (void)tapped:(UITapGestureRecognizer *)gesture
and in this method's body, you'll have to figure out the language.
Cheers,

iOS - Double tap on uibutton

I have a button and I'm testing the taps on it, with one tap it change a background color, with two taps another color and with three taps another color again.
The code is:
- (IBAction) button
{
UITapGestureRecognizer *tapOnce = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapOnce:)];
UITapGestureRecognizer *tapTwice = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapTwice:)];
UITapGestureRecognizer *tapTrice = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapTrice:)];
tapOnce.numberOfTapsRequired = 1;
tapTwice.numberOfTapsRequired = 2;
tapTrice.numberOfTapsRequired = 3;
//stops tapOnce from overriding tapTwice
[tapOnce requireGestureRecognizerToFail:tapTwice];
[tapTwice requireGestureRecognizerToFail:tapTrice];
//then need to add the gesture recogniser to a view - this will be the view that recognises the gesture
[self.view addGestureRecognizer:tapOnce];
[self.view addGestureRecognizer:tapTwice];
[self.view addGestureRecognizer:tapTrice];
}
- (void)tapOnce:(UIGestureRecognizer *)gesture
{
self.view.backgroundColor = [UIColor redColor];
}
- (void)tapTwice:(UIGestureRecognizer *)gesture
{
self.view.backgroundColor = [UIColor blackColor];
}
- (void)tapTrice:(UIGestureRecognizer *)gesture
{
self.view.backgroundColor = [UIColor yellowColor];
}
The problem is that the first tap don't works, the other yes.
If I use this code without button it works perfectly.
Thanks.
If you want the colors to change on tap of button, you should add these gestures on button in viewDidLoad method or so rather than on the same button action. The above code will repeatedly add gestures on tap of the button to the self.view and not on button.
- (void)viewDidLoad {
[super viewDidLoad];
UITapGestureRecognizer *tapOnce = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapOnce:)];
UITapGestureRecognizer *tapTwice = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapTwice:)];
UITapGestureRecognizer *tapTrice = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapTrice:)];
tapOnce.numberOfTapsRequired = 1;
tapTwice.numberOfTapsRequired = 2;
tapTrice.numberOfTapsRequired = 3;
//stops tapOnce from overriding tapTwice
[tapOnce requireGestureRecognizerToFail:tapTwice];
[tapTwice requireGestureRecognizerToFail:tapTrice];
//then need to add the gesture recogniser to a view - this will be the view that recognises the gesture
[self.button addGestureRecognizer:tapOnce]; //remove the other button action which calls method `button`
[self.button addGestureRecognizer:tapTwice];
[self.button addGestureRecognizer:tapTrice];
}

Tap Recognition for UIImageView in the UITableViewCell

Currently I'm facing a problem, I would like to perform action when the UIImageView on my UITableViewCell had been tapped.
Question: How could I do it? Could any one show me the code, or any tutorial?
Thanks in advance!
This is actually easier than you would think. You just need to make sure that you enable user interaction on the imageView, and you can add a tap gesture to it. This should be done when the cell is instantiated to avoid having multiple tap gestures added to the same image view. For example:
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super initWithCoder:aDecoder]) {
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(myTapMethod:)];
[self.imageView addGestureRecognizer:tap];
[self.imageView setUserInteractionEnabled:YES];
}
return self;
}
- (void)myTapMethod:(UITapGestureRecognizer *)tapGesture
{
UIImageView *imageView = (UIImageView *)tapGesture.view;
NSLog(#"%#", imageView);
}
Try this
//within cellForRowAtIndexPath (where customer table cell with imageview is created and reused)
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleImageTap:)];
tap.cancelsTouchesInView = YES;
tap.numberOfTapsRequired = 1;
[imageView addGestureRecognizer:tap];
// handle method
- (void) handleImageTap:(UIGestureRecognizer *)gestureRecognizer
{
RKLogDebug(#"imaged tab");
}
make sure u have....
imageView.userInteractionEnabled = YES;
you can use a customButton instead UIImageView
A tap gesture recogniser can be very memory hungry and can cause other things on the page to break. I would personally reconmend you create a custom table cell, insert a button into the custom cell frame and in the tableview code set the self.customtablecell.background.image to the image you want. This way you can assign the button an IBaction to make it push to whatever view you want.
Use ALActionBlocks to action in block
__weak ALViewController *wSelf = self;
imageView.userInteractionEnabled = YES;
UITapGestureRecognizer *gr = [[UITapGestureRecognizer alloc] initWithBlock:^(UITapGestureRecognizer *weakGR) {
NSLog(#"pan %#", NSStringFromCGPoint([weakGR locationInView:wSelf.view]));
}];
[self.imageView addGestureRecognizer:gr];