Simply I want to add a tap gesture for a UIImageView that when the user touches, calls a method that is implemented in another class (not the same class that contains the UIImageView).
Can I do this and if so how can i do it ?
You can do that. But you need the instance of the target class (class in which method is going to execute) as delegate or something in the gesture adding class.
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self.delegate action:#selector(doSomething)];
Here delegate will be the instance of the target class that you have to set before going to that class.
Edit
I will explain a little more. Suppose you have two view controller classes VCA and VCB. you want to call a method in VCA from VCB through a tap gesture.
in VCB.h
#property (nonatomic,assign)VCA *delegate;
in VCB.m
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self.delegate action:#selector(doSomething)];
in VCA.m
You will present/ push VCB
VCB * viewController = [[VCB alloc]init];
viewController.delegate = self;
// push or present viewController
Declare recognizer selector on init
UITapGestureRecognizer *recognizer =
[UITapGestureRecognizer
initWithTarget:objectOfAnotherClass
action:#selector(methodImplementedOnObjectOfAnotherClass:)];
dont forget about defining number of taps (numberOfTapsRequired) and optional gesture recognizer required to fail (requireGestureRecognizerToFail:)
Link to article about selector.
One straightforward approach is calling the method of another class from the selector method of tapGesture ie.
Add UITapGestureRecogniser to the imageview
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(tapRecognised)];
[imageView addGestureRecognizer:tapGesture];
Dont forget to enable the userInteraction of the UIImageView, because by default for imageview userInteraction is disabled.
you can do this like below.
imageView.userInteractionEnabled = YES;
Then in the selector of tapGestureRecogniser call the method of another class
- (void)tapRecognised
{
[next tappedOnImage];
}
Here next is the object of another class. You can use delegation also to call the method.
Hope this will help you.
here self.desired view is the view in which you want to add gesture and you should add gesture in following way
and "webViewTapped.delegate = self" means you want to call a function of the same class when user tap and you can change it to your desired function by using delegate like self.delegate
UITapGestureRecognizer *viewTapped = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapAction:)];
webViewTapped.numberOfTapsRequired = 1;
webViewTapped.delegate = self;
[self.desiredView addGestureRecognizer:viewTapped];
- (void)tapAction:(UITapGestureRecognizer *)sender;
{
// do your stuff here
}
Related
I want to add a gesture recognizer to a UIImageView in a UITableViewCell.
I've subclassed this cell, and implemented the gesture code, but it does not seem to be working .
This is the code for my subclassed .m file:
- (id)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder];
if (self) {
[self.settingsView setUserInteractionEnabled:YES];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(didRecognizeTapOnSettings)];
[tap setNumberOfTouchesRequired:1];
[tap setNumberOfTapsRequired:1];
[self.settingsView addGestureRecognizer:tap];
}
return self;
}
I'm using initwithcoder since I'm using storyboards, and that seems to be working far better than initwithframe. For some odd reason, didRecognizeTapOnSettings does not get called. I've set the delegate of the UIGestureRecognizer in my .h file as well.
IBOutlets are not yet set inside an init method, so self.settingsView is going to be nil. Move the code you have in the if(self) block to awakeFromNib, and then it should work.
try using
[tap setMinimumPressDuration:0.1f];
then you said you are setting your delegate for the gesture then if you are planning to use your delegate methods for the tapGesture you should set the delegate to self.
tap.delegate = self;
What's the hierarchy in your views? Your UITableViewCell might be catching the tap event instead of your UIImageView. As an experiment try to disable the userInteractions in the UITableViewCell contentView I'm assuming that you added the UIImageView in the contentView of your cell.
Let me know if that worked
I need to add several swipe gestures to my scene on a game. From what I know, this can only be done programmatically, unfortunately I have never added gestures in this way, I have always used IB. I know I need to initialize a gesture recognizer, using initWithTarget:action: and I know how to set its properties, what I don't know is how to make this gesture do stuff. I assume it is through the action parameter #selector but this seems to never get called. Am I doing this wrong? here is what I have:
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self
action:#selector(animateSwipeRightLeft)];
[self.view addGestureRecognizer:swipeRight];
and for the selector I have:
-(void)animateSwipeRightLeft {
//do stuff...
}
so it comes down to a few related questions: am I setting this up correctly? if so, why is my selector not being called? and if I am wrong about not being able to do this with IB, how?
also, if it helps, my gestures are set up in the initWithSize method for my scene.
You should add gesture recognizers in SKScene's didMoveToView method.
- (void)didMoveToView:(SKView *)view {
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self
action:#selector(animateSwipeRightLeft)];
[self.view addGestureRecognizer:swipeRight];
}
self.view is nil inside init methods
I have a UIView that already has a UIPanGesture implemented that works when a user drags the UIView half way up causing some action. As of now, it works just fine. Now, within the same UIView I want to implement a a UISwipeGesture so when the user swipes up, some other method would be called. I've been reading about the UIGestureRecognizerDelegate methods and I'm thinking I need to use gestureRecognizer:shouldRequireFailureOfGestureRecognizer: but I'm not sure.
I implemented the following in my viewDidLoad and got an error saying "invalid argument. Unrecognized selector sent to instance"
UIPanGestureRecognizer * panRec = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePan:)];
panRec.delegate = self;
[panedView addGestureRecognizer:panRec];
UISwipeGestureRecognizer * swipeRec = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipe:)];
swipeRec.direction = UISwipeGestureRecognizerDirectionUp;
swipeRec.delegate=self;
[panedView addGestureRecognizer:swipeRec];
[self gestureRecognizer:swipeRec shouldRequireFailureOfGestureRecognizer: panRec];
gestureRecognizer:shouldRequireFailureOfGestureRecognizer: is a delegate of the the UIGestureRecognizer. Meaning , you will implement the method , and when a gesture happens this method will be called automatically . To enable the gesture recognisers calling this method you need to set the gesture recogniser delegate to self, this can be done in viewDidLoad.
I have a UIView called myView on myViewController. I have a UIGestureRecognizer called swipeLeft (code below) that detects when a user swipes left on it.
The problem is: myViewController recognises the same gesture on the whole screen and performs another action. So I would like my app to perform myMethod when you swipeLeft in this particular area of myViewController, the area being myView.
UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self
action:#selector(myMethod:)];
swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
swipeLeft.delaysTouchesBegan = YES;
[self.myView addGestureRecognizer:swipeLeft];
More details: I am using RESideMenu and myViewController is the right menu, so when it is visible, the whole view of myViewController recognises swipes in all directions. I would like to change the recogniser in this particular UIView myView.
Thanks!
First you will need to add the swipe gesture to your view controllers header file.
#property (strong, nonatomic) UISwipeGestureRecognizer *swipeLeft;
If you look in DEMORootViewController.m, you will see this call:
self.rightMenuViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"rightMenuViewController"];
This will call your awakeFromNib, and it's your first chance to do something. In here you will create that swipe gesture. You can not add it to your view yet though, because your outlets are not set at this point. The first time they are set is in viewDidLoad, so that's where you will add the gesture to your view. So add this to your view controllers implementation file
- (void)awakeFromNib
{
self.swipeLeft = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:#selector(myMethod:)];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self.swipeView addGestureRecognizer:self.swipeLeft];
}
- (void)myMethod:(UISwipeGestureRecognizer *)swipe
{
NSLog(#"Did swipe") ;
}
Finally you will need to tell the pan gesture in RESideMenu.m to fail whenever our swipeLeft gesture occurs. The way to do that is to add the following code to RESideMenu.m at line 220. That's at the end of the viewDidLoad method.
if ([self.rightMenuViewController isKindOfClass:[DEMOVC class]]) {
DEMOVC *rightVC = (DEMOVC *)self.rightMenuViewController;
if (rightVC.swipeLeft) {
[panGestureRecognizer requireGestureRecognizerToFail:rightVC.swipeGesture];
} } }
This is assuming your custom VC is called DEMOVC. You will also need to import your custom VC to RESideMenu.m like this:
#import "DEMOVC.h"
Please let me know if this worked out for you, and if there's something else I can help you with.
I'm using UITapGestureRecognizer because I'm using a UIScrollView that acts as a container for my UILabels. Basically I'm trying to use an action method with arguments so I can e.g. send myLabel.tag value to the action method to know what action to take depending on what UILabel has has been triggered by a tap.
One way of doing it is having as many action methods as UILabels but that isn't very "pretty" codewise. What I would like to achieve is just having one action method with switch statements.
Is this possible or will I have to do it like this (sigh):
UITapGestureRecognizer *myLabel1Tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(myLabel1Tap)];
[myLabel1Tap addGestureRecognizer:myLabel1Tap];
UITapGestureRecognizer *myLabel2Tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(myLabel2Tap)];
[myLabel1Tap addGestureRecognizer:myLabel2Tap];
UITapGestureRecognizer *myLabelNTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(myLabelNTap)];
[myLabel1Tap addGestureRecognizer:myLabelNTap];
- (void)myLabel1Tap {
// Perform action
}
- (void)myLabel2Tap {
// Perform action
}
- (void)myLabelNTap {
// Perform action
}
Add a single gesture recognizer to the view that is the superview of your various labels:
UITapGestureRecognizer *myLabelTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(myLabelTapHandler:)];
[myLabelParent addGestureRecognizer:myLabelTap];
Then when you handle the gesture, determine which label was tapped:
-(void)myLabelTapHandler:(UIGestureRecognizer *)gestureRecognizer {
UIView *tappedView = [gestureRecognizer.view hitTest:[gestureRecognizer locationInView:gestureRecognizer.view] withEvent:nil];
// do something with it
}
You can use just one UITapGestureRecognizer and in your gesture handler (your myLaberXTap), which has the syntax:
- (void)handleGesture:(UITapGestureRecognizer*)gestureRecognizer {
...
}
use gesture.view to know which view you are working on.