【问题标题】:Ignore gestures on parent view忽略父视图上的手势
【发布时间】:2014-04-15 14:18:50
【问题描述】:

我最近遇到了一个问题,我有一个需要可滑动的超级视图和一个也需要可滑动的子视图。如果滑动发生在其范围内,则交互是子视图应该是唯一一个被滑动的视图。如果滑动发生在子视图之外,则父视图应处理滑动。

我找不到任何可以解决这个确切问题的答案,最终想出了一个 hacky 解决方案,如果它可以帮助其他人,我想我会发布。

编辑: 现在将更好的解决方案标记为正确答案。

将标题从“忽略触摸事件...”更改为“忽略手势...”

【问题讨论】:

    标签: objective-c subview uitouch superview


    【解决方案1】:

    如果您正在寻找更好的解决方案,您可以使用gestureRecognizer:shouldReceiveTouch:委托方法来忽略父视图识别器的触摸。

    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
           shouldReceiveTouch:(UITouch *)touch{
      UIView* swipeableSubview = ...; //set to the subview that can be swiped
      CGPoint locationInSubview = [touch locationInView:swipeableSubview];
      BOOL touchIsInSubview = [swipeableSubview pointInside:locationInSubview withEvent:nil];
      return !touchIsInSubview;
    }
    

    这将确保父级仅在滑动未在可滑动子视图上开始时收到滑动。

    【讨论】:

    • 我现在要试试这个!
    • 这是一个更好的解决方案。看起来更干净,更少hacky。最重要的是,它有效!
    【解决方案2】:

    基本前提是捕捉触摸发生的时间,如果触摸发生在一组视图中,则移除手势。然后在手势识别器处理手势后重新添加手势。

    @interface TouchIgnorer : UIView
    @property (nonatomic) NSMutableSet * ignoreOnViews;
    @property (nonatomic) NSMutableSet * gesturesToIgnore;
    @end
    @implementation TouchIgnorer
    - (id) init
    {
        self = [super init];
        if (self)
        {
            _ignoreOnViews = [[NSMutableSet alloc] init];
            _gesturesToIgnore = [[NSMutableSet alloc] init];
        }
        return self;
    }
    - (BOOL) pointInside:(CGPoint)point withEvent:(UIEvent *)event
    {
        CGPoint relativePt;
        for (UIView * view in _ignoreOnViews)
        {
            relativePt = [view convertPoint:point toView:view];
            if (!view.isHidden && CGRectContainsPoint(view.frame, relativePt))
            {
                for (UIGestureRecognizer * gesture in _gesturesToIgnore)
                {
                    [self removeGestureRecognizer:gesture];
                }
                [self performSelector:@selector(rebindGestures) withObject:self afterDelay:0];
                break;
            }
        }
        return [super pointInside:point withEvent:event];
    }
    
    - (void) rebindGestures
    {
        for (UIGestureRecognizer * gesture in _gesturesToIgnore)
        {
            [self addGestureRecognizer:gesture];
        }
    }
    @end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-25
      • 2011-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多