我最近遇到一个问题,我有一个需要可移动的超级视图和一个也需要可以移动的子视图。相互作用是,如果滑动发生在其范围内,则子视图应该是唯一滑动的子视图。如果滑动发生在子视图之外,则superview应该处理滑动。
我无法找到解决这个确切问题的任何答案,并最终想出了一个我认为如果可以帮助其他人而发布的hacky解决方案。
编辑: 现在,更好的解决方案被标记为正确答案。
更改标题来自"忽略触摸事件......"到"忽略手势..."
答案 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