忽略父视图上的手势

时间:2014-04-15 14:18:50

标签: objective-c subview uitouch superview

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

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

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

更改标题来自"忽略触摸事件......"到"忽略手势..."

2 个答案:

答案 0 :(得分: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;
}

如果刷卡未在可滑动的子视图上启动,这将确保父级仅接收滑动。

答案 1 :(得分:0)

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

@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