Limit Gesture Recognizer to Only One Specific UIView? - ios

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.

Related

Hide an imageview by clicking it?

When tapping a specific button in my app I want an image to show, I did this using an UIImageView. Then I want to hide that image by tapping it, but I don't understand how to do this?
I tried the following code, but it doesn't work.
#implementation ViewController
-(IBAction)pic {
UIImage *img = [UIImage imageNamed:#"test.png"];
[ImageView setImage:img];
imageView.userInteractionEnabled = YES;
UITapGestureRecognizer *tapRecognize = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(handleTap:)];
tapRecognizer.delegate = self;
[imageView addGestureRecognizer:tapRecognizer];
}
- (void)handleTap:(UITapGestureRecognizer *)tapGestureRecognizer {
//handle tap
}
Its pretty simple.
Use an UIImageView instead and check that userInteractionEnabled is YES on the UIImageView. Then you can then add a gesture recognizer.
Your .h file should have atleast something like below:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UIGestureRecognizerDelegate>
#property (weak, nonatomic) IBOutlet UIImageView *touchImageView;
#end
Dont forget to connect UIImageView from your storyboard to property declared above.
in your .m file:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.touchImageView.userInteractionEnabled = YES;
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(handleTap:)];
tapRecognizer.delegate = self;
[self.touchImageView addGestureRecognizer:tapRecognizer];
}
- (void)handleTap:(UITapGestureRecognizer *)tapGestureRecognizer {
//handle tap
self.touchImageView.alpha = 0.0f;
}
You could put an image on a button instead. I think using a UIImageView is the right decision though. You need to hook up a gesture to it programmatically. You can do this using something similar to below:
let singleFingerTap = UITapGestureRecognizer(target: self, action: "viewTapped:")
imageView.addGestureRecognizer(singleFingerTap)
You can add a tap gesture recognizer to the UIImageView that contains the image.
var tapGesture = UITapGestureRecognizer(target: <#AnyObject#>, action: <#Selector#>)
In the method you assign as the action, just set myImageView.alpha = 0. This should essentially "hide" your image view. You could also set the height of the image view to 0 if you wanted to hide it in that sense.
An alternative could be to import an open-sourced project, such as the AKImageViewer, to get posts to appear full screen (giving the user a better full view) and allowing them to swipe or cancel to get away from the image (similar to viewing images in the Twitter app.

UIScreenEdgePanGestureRecognizer does not react to view controller

I have a view controller that have a label, and I want to perform panning to the right on that label.
So what I did so far is:
*add a pan gesture to the label in the nib file
*created a didPan method:
- (IBAction)didPan:(UIScreenEdgePanGestureRecognizer *)sender;
and the implementation:
- (IBAction)didPan:(UIScreenEdgePanGestureRecognizer *)sender {
CGPoint newTranslation = [sender translationInView:self.homeLabel];
self.homeLabel.transform = CGAffineTransformMakeTranslation(newTranslation.x, 0);
}
and changed the screen edge pan gesture recogniser to right.
I thought it should pan now but its now, what am I doing wrong?
tnx
So I had some time to try it out myself.
Here's what the Interface Builder looks like with -didPan IBAction connected.
However that didn't work for me. I did some searching and found this also on StackOverflow.
Possible bug with UIScreenEdgePanGestureRecognizer in Interface Builder
So, I would suggest you try implementing it the old fashion way in code.
Try this:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIScreenEdgePanGestureRecognizer *swipeFromLeft = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:#selector(didPan:)];
swipeFromLeft.edges = UIRectEdgeLeft;
[self.view addGestureRecognizer:swipeFromLeft];
UIScreenEdgePanGestureRecognizer *swipeFromRight = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:#selector(didPan:)];
swipeFromRight.edges = UIRectEdgeRight;
[self.view addGestureRecognizer:swipeFromRight];
}

how to add a gesture to skView?

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

Subview and UIWebView UIGesture doesn't work

I recently got into trouble with a View Controller which has a UIWebView in it and a subview which I would like to add to the View Controller.
That's the View with the UIWebView:
http://cl.ly/image/03473l0e3a2L
My target is, to add a Share Menu which does work without problems:
http://cl.ly/image/3b273t2o3P00
But now I have the problem, that I set gesture recognizers for the social icons + labels (twitter,facebook,mail) - but these gesture recognizers don't do anything.
The ShareView is a UIView Subclass and I add the Gesture Recognizers this way:
UITapGestureRecognizer *fbTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(fbTapped:)];
fbTap.numberOfTapsRequired = 1;
fbTap.numberOfTouchesRequired = 1;
fbTap.delegate = self;
[fbImage addGestureRecognizer:fbTap];
[fbLabel addGestureRecognizer:fbTap];
UITapGestureRecognizer *twTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(twTapped:)];
twTap.numberOfTapsRequired = 1;
twTap.numberOfTouchesRequired = 1;
twTap.delegate = self;
[twImage addGestureRecognizer:twTap];
[twLabel addGestureRecognizer:twTap];
UITapGestureRecognizer *mailTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(mailTapped:)];
mailTap.numberOfTapsRequired = 1;
mailTap.numberOfTouchesRequired = 1;
mailTap.delegate = self;
[mailImage addGestureRecognizer:mailTap];
[mailLabel addGestureRecognizer:mailTap];
I think the Label and the UIImageView names do explain themselves. Every Label and ImageView has set userInteractionEnabled to YES. The ShareView is also enabled for Userinteractions and I did set UIGestureRecognizerDelegate to it.
The fbTapped,mailTapped and twTapped functions do send a Notification to the Main View (the view which has the webview and the ShareView in it).
But now when I click on the labels or imageviews, nothing happendes.
I did read on stackoverflow that the UIWebView in the MainView could interrupt the recognization? But I don't know how to solve this problem.
Would be really happy If you could help me or point me into the right direction to solve this problem.
I hope this piece of code will point you to the right direction:
1.Add a gesture recognizer delegate :
#interface myclass <UIGestureRecognizerDelegate>
{
//Whatever you are doing with gestures
}
2.Implement the delegate method:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
//Do your stuff
return YES;
}
check if the control reaches this delegate

Adding a tap Gesture that calls a method in another class

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
}

Resources