RotationGesture not call when PinchGesture active - ios

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];

Related

How to implement Swipe and Hold gesture recognizer in Objective-C?

I am working on an application which works like a remote control of different devices like Game Console, Set-top Box, etc.
Application contains different type of controls like gesture and buttons to perform events as remote.
Single gesture view contains multiple gesture recognizer as follow:
1 finger Tap using UITapGestureRecognizer
2 finger Tap using UITapGestureRecognizer
1 finger swipe using UISwipeGestureRecognizer
2 finger swipe using UISwipeGestureRecognizer
My requirement is to implement 1 finger Swipe gesture recognizer along with hold event. So, that will continue my swipe action until user will not remove its finger from the view.
I have tried UILongPressGestureRecognizer after UISwipeGestureRecognizer but this didn’t work for me because it is executing along with Swipe movement. And I want this after Swipe end, but finger will not remove.
My code snippet :
-(void) gestureView:(UIView*)viewGesture {
UISwipeGestureRecognizer *swipeGestureSingleRight;
UISwipeGestureRecognizer *swipeGestureSingleLeft;
UISwipeGestureRecognizer *swipeGestureSingleUp;
UISwipeGestureRecognizer *swipeGestureSingleDown;
swipeGestureSingleUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeGestureSingle_Handle:)];
[swipeGestureSingleUp setDelegate:self];
[swipeGestureSingleUp setDirection:(UISwipeGestureRecognizerDirectionUp)];
[swipeGestureSingleUp setNumberOfTouchesRequired:1];
[viewGesture addGestureRecognizer:swipeGestureSingleUp];
swipeGestureSingleDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeGestureSingle_Handle:)];
[swipeGestureSingleDown setDelegate:self];
[swipeGestureSingleDown setDirection:(UISwipeGestureRecognizerDirectionDown)];
[swipeGestureSingleDown setNumberOfTouchesRequired:1];
[viewGesture addGestureRecognizer:swipeGestureSingleDown];
swipeGestureSingleRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeGestureSingle_Handle:)];
[swipeGestureSingleRight setDelegate:self];
[swipeGestureSingleRight setDirection:(UISwipeGestureRecognizerDirectionRight)];
[swipeGestureSingleRight setNumberOfTouchesRequired:1];
[viewGesture addGestureRecognizer:swipeGestureSingleRight];
swipeGestureSingleLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(swipeGestureSingle_Handle:)];
[swipeGestureSingleLeft setDelegate:self];
[swipeGestureSingleLeft setDirection:(UISwipeGestureRecognizerDirectionLeft)];
[swipeGestureSingleLeft setNumberOfTouchesRequired:1];
[viewGesture addGestureRecognizer:swipeGestureSingleLeft];
longPressGestureOnSwipe = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(longPressGesture_Handle:)];
longPressGestureOnSwipe.minimumPressDuration = 0.03;
longPressGestureOnSwipe.delegate = self;
[viewGesture addGestureRecognizer:longPressGestureOnSwipe];
isSwipeEnd = false;
[longPressGestureOnSwipe setEnabled:isSwipeEnd];
}
- (void)swipeGestureSingle_Handle:(UISwipeGestureRecognizer*)sender {
if (sender.state == UIGestureRecognizerStateEnded) {
singleTouchSwipeSenderDirection = sender.direction;
isSwipeEnd = true;
[longPressGestureOnSwipe setEnabled:isSwipeEnd];
}
}
-(void)longPressGesture_Handle:(UILongPressGestureRecognizer*)sender {
if (sender.state == UIGestureRecognizerStateEnded) {
isSwipeEnd = false;
[longPressGestureOnSwipe setEnabled:isSwipeEnd];
}
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {
if (isSwipeEnd) {
[super touchesBegan:touches withEvent:event];
} else {
return;
}
}
Please suggest me correction or solution for my requirement.
Thanks in advance!

Getting UIPanGesture and UISwipeGesture working together in the same direction

I've set up my UIView to call a method when the view is panned up and to call some other method when the view is swiped up. My pan works fine and I can keep my pan disabled if my velocity.y is above a certain limit, but I can never get the swipe action to work when my pan fails. I've tried playing around with the delegate methods without much luck. Looked over this solution but no luck: https://stackoverflow.com/a/21728621/1925859
- (void)viewDidLoad
{
[super viewDidLoad];
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.delegate = self;
[panedView addGestureRecognizer:swipeRec];
[swipeRec requireGestureRecognizerToFail:panRec];
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]])
{
UIPanGestureRecognizer *pan = (UIPanGestureRecognizer *)gestureRecognizer;
CGPoint velocity = [pan velocityInView:gestureRecognizer.view];
if (ABS(velocity.y) > 200)
{
NSLog(#"Swipe actiavted");
return NO;
}
}
return YES;
}
- (IBAction)handleSwipe:(UISwipeGestureRecognizer *)recognizer
{
NSLog(#"In Swipe");
if(recognizer.direction == UISwipeGestureRecognizerDirectionUp)
{
panedView.frame =CGRectOffset( panedView.frame, 0, -1*self.view.bounds.size.height*.80);
}
}
If you remove your delegate method, add direction to the swipe and change the receiver of requireGestureRecognizerToFail then it will work. Note that pans must be way slower than sweeps in order to be recognized.
- (void)viewDidLoad
{
[super viewDidLoad];
UIPanGestureRecognizer * panRec = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePan:)];
[panedView addGestureRecognizer:panRec];
UISwipeGestureRecognizer * swipeRec = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipe:)];
swipeRec.direction = UISwipeGestureRecognizerDirectionUp;
[panedView addGestureRecognizer:swipeRec];
[panRec requireGestureRecognizerToFail:swipeRec];
}
- (IBAction)handleSwipe:(UISwipeGestureRecognizer *)recognizer
{
NSLog(#"In Swipe");
if(recognizer.direction == UISwipeGestureRecognizerDirectionUp)
{
panedView.frame =CGRectOffset( panedView.frame, 0, -1*self.view.bounds.size.height*.80);
}
}
- (IBAction)handlePan:(UISwipeGestureRecognizer *)recognizer
{
NSLog(#"PAN");
}

IBOutletCollection and UITapGesture

I'm trying to add a UILongPressGestureRecognizer and a UITapGestureRecognizer to an IBOutletCollection of UIImageViews, but it's not working. Here's the code I'm using:
UILongPressGestureRecognizer *pressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:#selector(deleteImage:)];
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(selectImage:)];
pressRecognizer.delegate = self;
tapRecognizer.delegate = self;
for (UIImageView *imageView in myImageViewCollection)
{
[imageView addGestureRecognizer:pressRecognizer];
[imageView addGestureRecognizer:tapRecognizer];
imageView.userInteractionEnabled = YES;
}
- (void)selectImage:(UITapGestureRecognizer *)sender
{
NSLog(#"Select");
}
- (void)deleteImage:(UILongPressGestureRecognizer *)sender
{
NSLog(#"Delete");
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
I've conformed to the UIGestureRecognizerDelegate. What am I doing wrong?
Refer to this question. Sounds like the same issue. I recreated your problem and the gesture recognizers are only bound to the last view.

UISwipeGestureRecognizer blocked by UITapGestureRecognizer

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;
}

IBAction does not fire when I add viewDidLoad

I have several IBActions attached to UIButtons. The IBActions work fine until I add the following code:
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"View Did Load");
[self addGestureRecognizersToView:drawImage];
}
After I add that chunk of code the IBActions do not fire. The UIButtons highlight when I touch them, but none of the IBAction code gets hit.
Here is my addGestureRecognizers code:
- (void)addGestureRecognizersToView:(UIImageView *)theView {
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePan:)];
[panGesture setMaximumNumberOfTouches:2];
[panGesture setMinimumNumberOfTouches:1];
//panGesture.delegate = drawImage;
[theView addGestureRecognizer:panGesture];
[panGesture release];
UITapGestureRecognizer *doubleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleTap:)];
[doubleFingerTap setNumberOfTapsRequired:2];
[self.view addGestureRecognizer:doubleFingerTap];
[doubleFingerTap release];
UITapGestureRecognizer *singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
[singleFingerTap setNumberOfTapsRequired:1];
[self.view addGestureRecognizer:singleFingerTap];
[singleFingerTap release];
}
If I comment out the singleFingerTap code it works. I'm guessing I should not be using alloc since I have already alloced that once before in doubleFingerTap?
Any ideas on what I might be missing here?
You single finger tap is hindering with the normal behavior of the button. You will have to make sure the touches get through unhindered.
[singleFingerTap setCancelsTouchesInView:NO];
It sounds like the UITapGestureRecognizer is intercepting the taps that would otherwise have been handled by the UIButtons.
You can use gestureRecognizer:shouldReceiveTouch::
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
return (touch.view != self.button1 &&
touch.view != self.button2);
}
Alternatively, you could hack the responder chain.

Resources