1

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

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

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

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

4

2 回答 2

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;
}

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

于 2014-04-15T14:44:14.407 回答
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
于 2014-04-15T14:18:50.273 回答