如何阻止从superview到子视图的手势?

时间:2013-06-07 08:37:33

标签: ios uiview uigesturerecognizer

我正在编写一个模块,每次我在视图上滑动时,都会添加两个具有视图大小的子视图。这些子视图有自己的手势(例如:pan,...)。我第一次滑动,没关系,因为没有创建子视图。但是一旦创建了子视图,每次我滑动时,滑动手势都会传递到其子视图。 :(,所以我必须滑动2次才能分开。

我想知道有没有办法阻止滑动传递到其子视图?谢谢。

更新
我使用了shouldRecognizeSimultaneouslyWithGestureRecognizer来使这些手势同时工作。但是仍然存在一些问题。父视图具有其滑动手势,子视图具有其手势。由于我使用souldRecognizeSimultaneouslyWithGestureRecognizer,有时当我平移时,滑动手势会触发。那么,你知道在这种情况下Pan是否处于活动状态时如何禁用Swipe?

6 个答案:

答案 0 :(得分:13)

您必须实现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;

在这里,检测您是否已经提交了子视图,并阻止了您想要的任何手势。

答案 1 :(得分:2)

将userinteractionEnabled设置为子视图的NO

 subview.userinteractionEnabled=NO

如果您不想禁用userInteraction,请使用cancelsTouchesInView方法

  

cancelsTouchesInView - 如果手势识别器识别出其手势,   它从他们的视角中取消了该手势的剩余触摸(所以   窗口不会传递它们)。窗口取消之前的   使用(touchesCancelled:withEvent :)消息传递触摸。如果一个   手势识别器无法识别其手势,视图会收到   多触摸序列中的所有触摸。

答案 2 :(得分:1)

要阻止来自超级视图的所有手势识别器,我创建了一个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]];
}

答案 3 :(得分:0)

尝试这样,

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

答案 4 :(得分:0)

考虑到我dialogView作为UIViewControllerview的直接子视图,我将手势识别器附加到主{{1}并执行以下操作(将我的视图控制器设置为手势识别器view

delegate)

答案 5 :(得分:0)

把我在这里读到的东西做成一个对我来说很棒的Swift 5!我在一个视图中有一个滑动控件,它也有一个滑动识别器,可以移动到另一个视图。如果手指没有碰到滑块的拇指,那么整个视图就会移动。

通过将此视图放置在滑块下(展开使其更大),错过不会做任何事情。

final class BlockingView: UIView, UIGestureRecognizerDelegate {
    let swipe: UISwipeGestureRecognizer = UISwipeGestureRecognizer();

    init() {
        super.init(frame: CGRect.zero)

        swipe.direction = [.left, .right]
        self.addGestureRecognizer(swipe)
    }
    required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }

    @objc override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { return false }
}

希望这可以避免麻烦!