I have a view which needs to handle pan, tap, and swipe gestures. I have pan and tap working, but when I add swipe, it doesn't work. Curiously, it seems that tap somehow blocks the swipes because if I remove the tap, then swipe works fine. Here's how I create my gesture recognizers.
- (void) initGestureHandlers
{
UISwipeGestureRecognizer *swipeLeftGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeLeftGesture:)];
swipeLeftGesture.numberOfTouchesRequired = 1;
swipeLeftGesture.direction = UISwipeGestureRecognizerDirectionLeft;
[self addGestureRecognizer:swipeLeftGesture];
UISwipeGestureRecognizer *swipeRightGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeRightGesture:)];
swipeRightGesture.numberOfTouchesRequired = 1;
swipeRightGesture.direction = UISwipeGestureRecognizerDirectionRight;
[self addGestureRecognizer:swipeRightGesture];
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTapGesture:)];
[tapGesture setNumberOfTapsRequired:1];
[self addGestureRecognizer:tapGesture];
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePanGesture:)];
[self addGestureRecognizer:panGesture];
}
A lot of blog suggest using requireGestureRecognizerToFail to handle the case where tap fires before the double tap fires, so I tried that, but it also didn't work.
[tapGesture requireGestureRecognizerToFail:swipeLeftGesture];
[tapGesture requireGestureRecognizerToFail:swipeRightGesture];
How can I get tap and swipe in the same view?
comment or remove the lines
//[tapGesture requireGestureRecognizerToFail:swipeLeftGesture];
//[tapGesture requireGestureRecognizerToFail:swipeRightGesture];
Also set the all the guesture objects delegate to self. like this
- (void) initGestureHandlers
{
UISwipeGestureRecognizer *swipeLeftGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeLeftGesture:)];
swipeLeftGesture.numberOfTouchesRequired = 1;
swipeLeftGesture.direction = UISwipeGestureRecognizerDirectionLeft;
swipeLeftGesture.delegate = self;
[self addGestureRecognizer:swipeLeftGesture];
UISwipeGestureRecognizer *swipeRightGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeRightGesture:)];
swipeRightGesture.numberOfTouchesRequired = 1;
swipeRightGesture = self;
swipeRightGesture.direction = UISwipeGestureRecognizerDirectionRight;
[self addGestureRecognizer:swipeRightGesture];
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTapGesture:)];
[tapGesture setNumberOfTapsRequired:1];
[self addGestureRecognizer:tapGesture];
tapGesture.delegate = self;
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePanGesture:)];
[self addGestureRecognizer:panGesture];
panGesture.delegate = self;
}
Implement the delegate method like this
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
put this one and try it,
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
{
return YES;
}
Related
I have a general touchesBegan in my viewcontroller
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(#"--[%s:%d]",__PRETTY_FUNCTION__,__LINE__);
}
This seems to cancel the UISwipeGestureRecognizer. (not fired)
UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipe:)];
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipe:)];
[swipeLeft setDirection:UISwipeGestureRecognizerDirectionLeft];
[swipeRight setDirection:UISwipeGestureRecognizerDirectionRight];
swipeRight.numberOfTouchesRequired=1;
swipeLeft.cancelsTouchesInView=NO;
swipeRight.cancelsTouchesInView=NO;
swipeLeft.delaysTouchesBegan = YES;
swipeRight.delaysTouchesBegan = YES;
self.viewSwipe.userInteractionEnabled=YES;
[self.viewSwipe addGestureRecognizer:swipeLeft];
[self.viewSwipe addGestureRecognizer:swipeRight];
Any idea? :)
touchesBegan:: gets called before any gesture recognizers, and will indeed override them.
If you wish to support both tap and swipe on the same view, you can use a UITapGestureRecognizer, and call requireGestureRecognizerToFail.
So, add the following to the bottom of your code sample:
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] init];
tapRecognizer.numberOfTapsRequired = 1;
[tapRecognizer requireGestureRecognizerToFail swipeLeft];
[tapRecognizer requireGestureRecognizerToFail swipeRight];
I have drawingView and listen UIPanGestureRecognizer, UIRotationGestureRecognizer, and UIPinchGestureRecognizer on it.
- (void)viewDidLoad
{
[super viewDidLoad];
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(panDetected:)];
[self.drawingView addGestureRecognizer:panRecognizer];
UIRotationGestureRecognizer *rotateRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotateRecognizer:)];
[self.drawingView addGestureRecognizer:rotateRecognizer];
UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(pinchRecognizer:)];
[self.drawingView addGestureRecognizer:pinchRecognizer];
[self.drawingView reloadData];
}
-(void) pinchRecognizer:(UIPinchGestureRecognizer*) recognizer {
return;
NSLog(#"Call scale");
}
- (void)rotateRecognizer:(UIRotationGestureRecognizer*)recognizer {
NSLog(#"Call rotaion");
}
If i only choose UIRotationGestureRecognizer or UIPinchGestureRecognizer it is perfect. But if using UIRotationGestureRecognizer and UIPinchGestureRecognizer only UIPinchGestureRecognizer called, UIRotationGestureRecognizer isn't called.
What is problem in my code?
I think i will make a UISegmented to choose mode , UIRotationGestureRecognizer or UIPinchGestureRecognizer, what should i do?
Thank a lot
If you want to have multiple gestures recognized at once, try using gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer, ex:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
Edit: In addition to including the delegate in your .h, make sure to set your UIGestureRecognizer's delegate's to self, ex:
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(panDetected:)];
panRecognizer.delegate = self;
[self.drawingView addGestureRecognizer:panRecognizer];
UIRotationGestureRecognizer *rotateRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotateRecognizer:)];
rotateRecognizer.delegate = self;
[self.drawingView addGestureRecognizer:rotateRecognizer];
Use requireGestureRecognizerToFail: to recognize the gesture if the other gesture recognizer did not executes.
[rotateRecognizer requireGestureRecognizerToFail: pinchRecognizer];
What are the different ways to recognize a UIButton being touched?
IBAction doesn't seem to be working with what I want, to my knowledge, I could probably use a gesture recognizer and check if the button's location was tapped, but is there any other way?
Try UITapGestureRecognizer.
//-- For identifing touch recognize
UITapGestureRecognizer *singleTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(touchIdentifier:)];
singleTapGestureRecognizer.numberOfTapsRequired = 1;
singleTapGestureRecognizer.enabled = YES;
singleTapGestureRecognizer.cancelsTouchesInView = NO;
[your_button addGestureRecognizer:singleTapGestureRecognizer];
Method for operation
-(void)touchIdentifier:(UITapGestureRecognizer*)gesture
{
NSLog(#" Current button ID %d \n",gesture.view.tag);
}
hello U can go with the UISwipe Recognier
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc]
initWithTarget:self action:#selector(handleSwipe:)];
swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
[imgView_ addGestureRecognizer:swipeRight];
[swipeRight release];
UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc]
initWithTarget:self action:#selector(handleSwipe:)];
swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
[imgView_ addGestureRecognizer:swipeLeft];
[swipeLeft release];
But DO NOT forget to set UserInteractionEnabled for the View
I add singTap and doubleTap to a view like the code below:
-(void)awakeFromNib{
[self setUserInteractionEnabled:YES];
//
UITapGestureRecognizer *doubleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleTapGesture:)];
doubleTapGesture.numberOfTapsRequired = 2;
[self addGestureRecognizer:doubleTapGesture];
UITapGestureRecognizer *singleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTapGesture:)];
singleTapGesture.numberOfTapsRequired = 1;
[self addGestureRecognizer:singleTapGesture];
}
-(void)handleSingleTapGesture:(UITapGestureRecognizer *)singleTapGesture{
[[self delegate] singleTapOnView];
}
-(void)handleDoubleTapGesture:(UITapGestureRecognizer *)doubleTapGesture{
[[self delegate] doubleTapOnView];
}
When doubleTap the singleTap also fire. How to disable singleTap when doubleTap? Thanks!
Tell the single-tap recognizer that it requires the double-tap recognizer to fail before it triggers:
[singleTapGesture requireGestureRecognizerToFail:doubleTapGesture];
(This is actually the canonical example in the UIGestureRecognizer docs for this method.)
I am trying to add 2 gestures to a uiimage that pulls a subVIew. One gesture is swipe to open/close. And the other is longpressand hold to open it at a specific height.
longPress.minimumPressDuration = 1;
[imageNavigationSlider addGestureRecognizer:longPress];
UILongPressGestureRecognizer *longPressWall = [[[UILongPressGestureRecognizer alloc]
initWithTarget:self action:#selector(handleLongPressWall:)] autorelease];
longPressWall.minimumPressDuration = 1;
PullMeImage.userInteractionEnabled=YES;
[PullMeImage addGestureRecognizer:longPressWall];
UISwipeGestureRecognizer *swipe = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipe:)] autorelease];
swipe.direction = UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight;
[PullMeImage addGestureRecognizer:swipe];
[swipe setDelegate:self];
The long press gesture is correctly recognized, but the swipe isn't.
I also tried using:
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
But with no success. Any help will be very much appreciated.
Thank you