Cancel gesture recognizer on button action - ios

I'm working on an iPad app. I have a view in which the user can draw with his finger. This view has a subview, which is a calculator, and which have buttons.
I would like that when the user touch a button, the superview (in which the user can draw) doesn't take into account this touch. (so the user doesn't draw when he touches the calculator)
Preferably, I would like to not change the code of the calculator view and the code of my superview. I have only access to them via properties of another class.
Is there a way to solve the problem please? I have tried exclusiveTouch, but it doesn't work.

If you have access to the button action and the drawing gesture you can simply set:
gesture.enabled = NO;
To cancel the current gesture processing and / or prevent it from starting. When you want to reenable the gesture depends on what type it is and how it's used but doing it immediately (on the next line) will probably work ok.

Try this but include UIGestureRecognizerDelegate in your header file.
This is from apple "SimpleGestureRecognizers" example-
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
// Disallow recognition of tap gestures in the segmented control.
if ((touch.view == YourButton))
{
//change it to your condition
return NO;
}
return YES;
}

Related

How to avoid to trigger a UIPanGestureRecognizer when there is a tap on a UIButton?

I have added UIPanGestureRecognizer on the view of my UIViewController.
In this view (a calculator) are some UIButton triggered by the event .TouchUpInside.
The problem comes if I tap on the button and make a small pan at the same time (which might happen if you tap quickly a button and are moving to the next one at the same time). Then the pan gesture is triggered. I would like to avoid it when there is a tap on a button. But I would like to allow it if the tap takes too long (let say 0.3s is enough to trigger the pan gesture).
How can I achieve that?
Set the property cancelsTouchesInView of your gesture recognizer to NO.
Then your button should work properly.
You can use the delegate method like this-
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
if ([touch.view isKindOfClass:[UIButton class]]) {
return NO;
}
return YES;
}
There is a dirty solution. You can just grab it in a UIScrollView

iOS gesture collisions between slider and pan gesture on controller

I am using ECSlidingViewController for hamburger menu and I added code to my viewDidLoad method:
[self.slidingViewController.topViewController.view addGestureRecognizer:self.slidingViewController.panGesture];
Now I have pan gesture to show right menu or to hide. It's okay. But I have on view slider and it's really hard to get him working. I must tap on exact position. Is it possible to set that in exact rectangle (in view that contains slider) the slider would be answering on gesture and on other parts it would be working as now?
And one more question. When I have navigation controller with table and then I went on detail and then I show right menu it's okay but when I want to close it by pan I first go back in navigation and then close menu. Is it possible to change this order?
Have you tried setting UIGestureRecognizerDelegate and handling the both gesture recognizes in similar fashion as described in FAO?
e.g.:
#pragma mark - UIGestureRecognizerDelegate
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
if ([otherGestureRecognizer.view isKindOfClass:[UISlider class]]) {
return YES;
} else {
return NO;
}
}

enable swipe on view controller, but disable within a view in that VC

I have a UIViewController where I have 2 UISwipeGestureRecognizers handling undo and redo (swipe right to undo, swiple left to redo). Within this VC I also have a UIView that is tracking touch began/moved/ended to change colors on another UIView. BTW, the undo/redo has to do with the color changes.
The problem I'm running into is that when I'm doing the touch events in the color changer view, they are sometimes interpreted as a swipe and undo/redo are happening.
How can I disable the swipe gestures just for the UIView in question but retain the ability to perform swipes on other areas of the VC?
Make the view controller a delegate of the gesture recognizer, then implement this delegate method:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
return touch.view != self.mySubviewToExclude;
}

use UILongPressGestureRecognizer on disabled UIButton

I have a UIButton that has an UILongPressGestureRecognizer attached to it.
If the button is enabled I receive events from the gestureRecognizer.
However, if the button is disabled (i.e. button.enabled = NO) I don't receive those event.
Is there any way to receive events from a UILongPressGestureRecognizer if the UIButton is not enabled?
A few options:
Don't actually disable the button, just set a flag internally and don't perform the button action when the flag is false. Side effect is that the button will still look like it's working.
Create another button over top of the disabled button that has no visible appearance. Attach a Long Press to that as well. When you enable the visible button, disable the invisible button and vice versa.
Put a Long Press on the parent view use the gesture delegate to see if it's on top of your button:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if (touch.view == theButton)
{
// Perform your action
}
}

Cancel touch on UIButton on touch move (iOS)

I have a view with button and touch-move gesture. When user touches button it becomes selected and keeps receiving touch-move events. I want to deselect the button on touch-move and pass moves to gesture.
How to cancel touch receiving on button "elegantly"?
Try the next line of code on Swift 4
youButton.touchesCancelled([], with: nil)
Works well with pan gesture reco
You need to implement the UIGestureRecognizerDelegate. Specifically this method. Then just build your logic for deciding if the gesture should receive the touch or not. If you return NO then the touch is up for grabs for the button. if you return YES the gesture to take the touch.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
If you never even more control I think you'll need to subclass the button and takeover its hit testing.

Resources