Как заблокировать жест из superview в subview?

Я пишу модуль, который каждый раз, когда я провожу по виду, будут добавлены два суб-вида с половиной размера представления. Эти подвиды имеют свои собственные жесты (например: кастрюля,...). В первый раз, когда я провожу, это нормально, потому что ни один из subview не был создан. Но как только подвидение было создано, каждый раз, когда я провожу, жест свайпа всегда переходит к его подвидам. : (, поэтому мне нужно провести 2 раза, чтобы разделить.

Я хочу знать, есть ли способ заблокировать салфетки, проходящие в его подвиде? Благодарить вы.

обновление
Я использовал shouldRecognizeSimultaneouslyWithgesturerecognizer, чтобы заставить эти жесты работать одновременно. Но есть еще кое-какие проблемы. У родительского вида есть свой жест салфетки, у подвида есть свой жест панорамирования. Поскольку я использую souldRecognizeSimultaneouslyWithgesturerecognizer, иногда, когда я панорамирую, срабатывает жест салфетки. Итак, вы знаете, как отключить салфетки, пока Pan активен в этой ситуации?

5 ответов


вы должны реализовать метод UIGestureRecognizerDelegate:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;

и добавьте контроллер в качестве делегата распознавателей жестов. Затем, когда два распознавателя жестов отвечают на жест, этот метод будет вызван, и здесь вы можете реализовать логику, которую хотите для своего приложения.

в объявлении интерфейса контроллера вы должны ввести:

@interface testcViewController () <UIGestureRecognizerDelegate>

затем, при создании распознавателя жестов:

UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe)];
swipe.direction = UISwipeGestureRecognizerDirectionDown;
swipe.delegate = self;
[self.view addGestureRecognizer:swipe];

и затем, наконец, вы добавляете этот метод к контроллеру:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    BOOL shouldInteract = NO;
    //Here you decide whether or not the two recognizers whould interact.
    return shouldInteract;
}

редактировать Вы также можете реализовать

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;

и здесь, обнаружить, если вы уже представили подвиды, и блокировать любой жест, который вы хотите.


установите userinteractionEnabled в NO вашего подвида

 subview.userinteractionEnabled=NO

Если вы не хотите отключать userInteraction, используйте cancelsTouchesInView метод

cancelsTouchesInView-если распознаватель жестов распознает его жест, это освобождает оставшиеся прикосновения этого жеста от их взгляда (так окно не доставит их). Окно отменяет предыдущее доставлены штрихи с сообщением (touchesCancelled:withEvent:). Если жест распознаватель не узнает свой жест, взгляд получает все касания в мультитач последовательности.


чтобы заблокировать все распознаватели жестов из superviews, я создал подкласс UIGestureRecognizer, который будет делать именно это при подключении к представлению. См. следующий код (взятый из моего проекта WEPopover):

#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

Если вы хотите заблокировать все распознаватели жестов, прикрепленные к родительским представлениям некоторого представления, просто сделайте следующее:

- (void)blockParentGesturesForView:(UIView *)v {
    [v addGestureRecognizer:[WEBlockingGestureRecognizer new]];
}

попробуйте вот так,

   - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
    return NO;
}

учитывая, что у меня есть dialogView в качестве прямого подвида my UIViewController ' s main view я прикрепляю распознаватель жестов к основному view и сделайте следующее (установка моего контроллера вида в качестве распознавателя жестов delegate):

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
    let point = touch.location(in: view)
    return !dialogView.frame.contains(point)
}