I'm writing a module that everytime I swipe on a view, two sub views with a half size of the view will be added. Those subviews have their own gestures (eg: pan,...). The first time I swipe, it's OK because none of subview has been created. But once the subview been created, everytime I swipe, the swipe gesture is alway pass to its subviews. :(, so I have to swipe 2 times to divide.
I want to know is there any way to block swipe passing to its subview? Thank you.
UPDATE
I used shouldRecognizeSimultaneouslyWithGestureRecognizer to make those gestures work simultaneously. But there's still have some problems. The parent view have its Swipe gesture, the subview have its Pan gesture. Since I use souldRecognizeSimultaneouslyWithGestureRecognizer, sometime when I'm panning, the swipe gesture triggers. So, you know how to disable Swipe while Pan is active in this situation?
You have to implement the UIGestureRecognizerDelegate method:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
And add your controller as the delegate of the gesture recognizers. Then, when two gesture recognizers respond to a gesture, this method will be called and here you can implement the logic you want for your app.
In the interface declaration of the controller you have to type:
@interface testcViewController () <UIGestureRecognizerDelegate>
Then, when creating the gesture recognizer:
UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe)];
swipe.direction = UISwipeGestureRecognizerDirectionDown;
swipe.delegate = self;
[self.view addGestureRecognizer:swipe];
And then, finally, you add this method to the controller:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
BOOL shouldInteract = NO;
//Here you decide whether or not the two recognizers whould interact.
return shouldInteract;
}
EDIT You can also implement
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;
And here, detect if you have already presented the subviews, and block any gesture you want.
To block all gesture recognizers from superviews I created a UIGestureRecognizer sub class that will do just that when attached to a view. See the following code (taken from my WEPopover project):
#import "WEBlockingGestureRecognizer.h"
#import <UIKit/UIGestureRecognizerSubclass.h>
@implementation WEBlockingGestureRecognizer
- (id)init {
return [self initWithTarget:self action:@selector(__dummyAction)];
}
- (id)initWithTarget:(id)target action:(SEL)action {
if ((self = [super initWithTarget:target action:action])) {
self.cancelsTouchesInView = NO;
}
return self;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
if (self.state == UIGestureRecognizerStatePossible) {
self.state = UIGestureRecognizerStateBegan;
}
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
self.state = UIGestureRecognizerStateRecognized;
}
- (BOOL)canBePreventedByGestureRecognizer:(UIGestureRecognizer *)preventingGestureRecognizer {
return [self isGestureRecognizerAllowed:preventingGestureRecognizer];
}
- (BOOL)canPreventGestureRecognizer:(UIGestureRecognizer *)preventedGestureRecognizer {
return ![self isGestureRecognizerAllowed:preventedGestureRecognizer];
}
- (BOOL)shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return ![self isGestureRecognizerAllowed:otherGestureRecognizer];
}
- (BOOL)shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return NO;
}
- (BOOL)isGestureRecognizerAllowed:(UIGestureRecognizer *)gr {
return [gr.view isDescendantOfView:self.view];
}
- (void)__dummyAction {
}
@end
If you want to block all gesture recognizers attached to parent views of some view, just do the following:
- (void)blockParentGesturesForView:(UIView *)v {
[v addGestureRecognizer:[WEBlockingGestureRecognizer new]];
}
set userinteractionEnabled to NO of your subView
subview.userinteractionEnabled=NO
if you dont want to disable userInteraction then use cancelsTouchesInView
method
cancelsTouchesInView—If a gesture recognizer recognizes its gesture, it unbinds the remaining touches of that gesture from their view (so the window won’t deliver them). The window cancels the previously delivered touches with a (touchesCancelled:withEvent:) message. If a gesture recognizer doesn’t recognize its gesture, the view receives all touches in the multi-touch sequence.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With