For example, I have a button, when click this button, it call an action: doAction1.
And an View: when touch in it, it call an action doAction2.
When clicked in this button, I touched in view, too.
Is it have any property to set priority to call doAction1 or doAction2?
I assume that you you put a Tapgesturerecogniyer to container view.You can ignore the tap gesture if user has tapped on the button.Just overwrite the fooling method
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
// test if touched view is unbutton
if ([touch.view isKindOfClass:[UIButton class]])
{
return NO; // ignore the touch
}
return YES;
}
Related
I have a gesture recognizer that I've made on a calculator. It's connected to an action that is activated upon a user's double tap. I connected the gesture recognizer to the main view of the view controller, however the gesture recognizer is also applied to my buttons. So if the user quickly types 11, they'll press 1 two times fast and accidentally activate a function that they don't want to. How do I make it so that the UIGestureRecognizer doesn't act upon buttons? I want to keep the double-tap gesture. I don't want to change it to a two finger tap or something odd like that. However, if there's no other way (which I doubt there is), I could do that.
Try this:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if ((touch.view == yourButton)) {
return NO;
}
return YES;
}
This will be called every time the gesture is recognized, and it will ignore the gesture is the view is your button.
You should adopt UIGestureRegconizerDelegate protocol in your ViewController.h
#interface ViewController : UIViewController <UIGestureRecognizerDelegate>
#end
in your ViewController.m, implement this method
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if ([touch.view isKindOfClass:[UIControl class]]){
return NO;
}
return YES;
}
and yourGestureRecognizer.delegate = self //your view controller.
Building on Antonio's answer, you could give all of your tags to make this easier. Presumably, your calculator has more than just one yourButton. Suppose all your buttons have a tag larger than 100:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldReceiveTouch:(UITouch *)touch {
if ((touch.view.tag > 100)) {
return NO;
}
return YES;
}
This is cleaner than checking the class of the view. You could now have controls where you allow the gesture to be recognised anyway.
I created a UIPanGestureRecognizer in a UICollectionViewCell subclass. It works in all cells except the top of the screen. About the height of status bar the pan gesture recognizer is dead. It doesn't fire. My test app only has a UICollectionView and nothing else. No status bar. I think maybe it has to do with the notification center "active edge" stealing touch events.
_panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(panGestureRecognized:)];
_panGestureRecognizer.delegate = self;
_panGestureRecognizer.maximumNumberOfTouches = 1;
[self addGestureRecognizer:_panGestureRecognizer];
At the top of screen when I pan in the cell I get no message upon pan begin. There is no call to the callback until I lift the finger. Then the callback receives BEGAN and immediately after that it receives ENDED.
- (void)panGestureRecognized:(UIPanGestureRecognizer*)sender {
NSLog(#"pan detected"); // for first cell, only called when finger is lifted up.
if (sender.state == UIGestureRecognizerStateBegan) {
NSLog(#"BEGAN");
} else if (sender.state == UIGestureRecognizerStateEnded) {
NSLog(#"ENDED");
}
}
The cell is the delegate of the gesture recognizer. It implements:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
The cell also overwrites the UIView method:
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
return YES;
}
Is this a known problem with pan gesture recognizers at the top of the screen? And is there a workaround?
I have a button and a gesture recognition and when the button is pressed only one method should be called.
Most cases only the gesture recognition is being called which is fine but every no and then the button gets called to which causes problems.
I have a view and then a scroll view. All my buttons are on the scroll view
you can implement this in your view controller and assign it to the delegate of the gesture recognizer.
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
CGPoint p = [gestureRecognizer locationInView:self.view];
UIView *view = [sefl.view hitTest:p withEvent:nil];
if ([view isKindOfClass:[UIButton class]]) {
return NO;
}
return YES;
}
or you can implement - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch with similar logic if gestureRecognizerShouldBegin: does not suit.
I have a main window xib on an iPad. The main window has tap gesture recognizers that show/hide a toolbar when the user taps the screen. There is also a web view in the main window.
How would I go about canceling the gestures if the user clicks a link in the web view? I don't want the toolbar to toggle if they hit a link.
Thanks
You need to check if the view should receive the touch implementing:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
// test if our control subview is on-screen
if (self.view.superview != nil) {
if ([touch.view isKindOfClass:[UIWebView class]]) {
// we touched our UIWebView
return NO; // ignore the touch
}
}
return YES; // handle the touch
}
If you want to use the UITapGestureRecognizer you need to subclass the UIWebView as explained here: https://github.com/psychs/iphone-samples/tree/4028ab78af92ab17465338575b78ed80310a613f/WebViewTappingHack
I have added Tap Gesture recognizer to a view. My view has an image and a UIToolBar at the bottom with a few UIBarbuttons I want to cancel any touches on these buttons. I am trying to use the following method to cancel the touch. How do I detect whether the touch is on the toolbar or any bar buttons? Frame is also not defined for Bar buttons...
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
if (gestureRecognizer == tapRecognizer) {
if (touch.view==barbutton/*toolbar or bar button item*/)
{
return NO;
}
}
return YES;
}
CGPoint location = [touch locationInView:self.view];
if(CGRectContainsPoint(toolbar.frame, location)) { ... }
This is assuming the toolbar and self.view are in the same coordinate space. If not, you'll have to use UIView's coordinate conversion methods (convertPoint:toView:) to make the spaces match.
Buttons are the first responder and their uitouchup or other event will fire first and won't propogate to the backing view.
You can subclass your buttons and have the touchesbegan/moved/ended do:
[self.nextResponder touchesBegan:touches withEvent:event];
to have your backing view handle all their events for them in which case your gesture code should work.