Two UIGestureRecognizers and UIButton - ios

I encountered this problem and was able to resolve it as described.
Gesture recognizer and button actions
But when I added a second UIGestureRecognizer to the same UIView the UIButton selector is not called for the second UIGestureRecognizer, only the first.
So I have a single UIView with two UIGestureRecognizers. There is a UIButton on the UIView.
The UIButton selector always get called correctly after the first UIGestureRecognizer. The first touch on the UIButton for the second UIGestureRecognizer does nothing, but the second touch on the UIButton works as expected.
If I remove the first UIGestureRecognizer from the view then the first UIButton press fires the selector as expected after the second gesture is performed.
Any idea why the first touch on the UIButton doesn't fire the selector but the second does?

try to put his delegate method in your viewController
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
returning YES to this method is guaranteed to allow simultaneous recognition.

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

UIButton and swipe-to-delete on UITableViewCell

I have a custom UITableViewCell with a UIButton.
UIButton blocks the swipe-to-delete gesture recognizer implemented by Apple; if the swipe starts on the button, the swipe is not recognized, otherwise the delete button appears and everything works correctly
At the moment, I have replace the UIButton by an UIImageView to get the desired behaviour.
I would like if somebody manages to make this work.
I have already tried to implement this delegate method
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
and searched the view/subviews for all its gesture recognizers and assign them the cell as delegate. I still can make it work with a UIButton.
I target ios8
Thanks
Use UILable or UIImage instead of UIButton, and set userInteractionEnabled to YES, and add a UITapGestureRecognizer gesture to it.

Handling multiple gestures simultaneously

I have two subviews view1 and view2. I have added LongPress and Pan gesture to my parentview.
When I longPress on view1, I will present a draggableview with popup animation just below the fingure and will continue dragging dragView to view2.
In this process panGesture selector is not called but Longpress gesture selector is called.
After i remove the fingure from dragview and then start dragging again then the panGesture selector is called.
What I need is, once the dragview is created, disable(not permanently but until pan gesture state ended is called) the longpress gesture and the pan gesture selector should be called
You have a delegate method called:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
Take a look at it, you need to return YES.

IBAction UIButton firing is delayed

I have a UIButton connected to an IBAction in Interface Builder.
The Problem:
The action firing and the de-highlight of the button both take a little bit to happen.
The Facts:
View structure:
View
10 Buttons (connected via UIControlEventTouchUpInside to the IBAction
View (Subview)
Gesture recognizer
Text Field
The Subview has a UITapGestureRecognizer, which delaysTouchesBegan and delaysTouchesEnded both are set to NO
The action is happening in the main thread.
Testing a simple button (with no images or title, and only a simple NSLog), the result is the same
The Question:
Why are firing and the de-highlight delayed?
In the end, I added somewhere some UIGestureRecognizer, and forgot to set delaysTouchesBegan to NO =(
Ok I think that because of the UITapGestureRecognizer .. try to do the following :
connect an IBOutlet to your button.
2.assing the UITapGestureRecognizer delegate to your ViewController.
3.Implement this gesture delegate method in yourViewController
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldReceiveTouch:(UITouch *)touch {
return (! [yourButton pointInside:[touch locationInView:yourButton] withEvent:nil]);
}
This will make the tap to be recognized to your button not to the recognizer.
Make sure your touch event is set the first contact of the button which would be the touch down event otherwise there will be a delay in the action until whichever other event you chose gets completed (i.e. touch up inside, touch up outside, etc).
In my case, there was a delay on IBAction for a button that was in a custom CalloutView of an MKAnnotationView.
In the same way there is a ~0.5sec delay between pressing the MKAnnotationView and the MKAnnotationView actually being selected, there is also a delay between any other user interactions you might add as a subview of the MKAnnotationView.
The solution is to disable the native UIGestureRecognizer within MapView that is causing the delay of any MKAnnotation view selections.
This can be done with the solution on this post:
Set isZoomEnabled = false within a gesture recognizer attached to the mapview on any tap, then set isZoomEnabled = false within a 0.5sec async dispatch.

How to pass to let a subview UIButton get the press event?

I have a view with a tap gesture and a UIButton on it with its corresponding action.
The problem is that If I press the button its corresponding action is not getting called instead the tap handler is getting called.
I did a hitTest and stopped the gesture-handler from doing anything if the hit was on the button.
But I am unable to let the button's action do something.
You can set your controller class to be the delegate of the UIGestureRecognizer and then implement this method:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
return [[touch view] isEqual:UIViewThatIsNotYourButton];
}
Your hitTest method should actually achieve this, so you might also check if the UIButton is really getting an action assigned to it.

Resources