如何防止点击子视图触发父视图上的 UITapGestureRecognizer?
Posted
技术标签:
【中文标题】如何防止点击子视图触发父视图上的 UITapGestureRecognizer?【英文标题】:How do I prevent taps on a subview from triggering a UITapGestureRecognizer on a parent view? 【发布时间】:2016-03-31 02:05:16 【问题描述】:我在视图中添加了一个点击识别器:
UITapGestureRecognizer* tgr = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector( onTap )];
[view addGestureRecognizer: tgr];
问题是点击view
的子视图会触发onTap
。我该如何预防?
【问题讨论】:
【参考方案1】:假设您的parentView
有一个subView
。你实现了下面的UIGestureRecognizerDelegate
方法,如果触摸在subView
的范围内,你返回no。
tgr.delegate = self;
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
CGPoint locationInView = [touch locationInView:self.parentView];
if (CGRectContainsPoint(self.subView.frame, locationInView) )
return NO;
else
return YES;
【讨论】:
这对我来说似乎比批准的答案更好。阻止点击,而不是添加更多什么都不做的识别器。【参考方案2】:将子视图添加到视图的背景,并将点击手势识别器附加到子视图:
UIView* subview = [[UIView alloc] initWithFrame:view.bounds];
subview.backgroundColor = [UIColor clearColor];//or view.backgroundColor
[view addSubview:subview];
[view sendSubviewToBack:subview];
[subview addGestureRecognizer:tapRecognizer];
【讨论】:
谢谢!即使在 Swift 4.0 中这也有效,这正是我正在寻找的一个简单的解决方案:) 我已经更改了代码,出现了一个小错误(您不应该使用视图的框架,使用边界来获取子视图的当前框架)。【参考方案3】:AlertView
的 Swift 4.2 答案
添加手势识别器并设置委托:
let backgroundViewTapGesture = UITapGestureRecognizer(target: self, action: #selector(dismiss))
backgroundViewTapGesture.delegate = self
self.backgroundView.addGestureRecognizer(backgroundViewTapGesture)
self.backgroundViewTapGesture = backgroundViewTapGesture
然后添加处理点击的扩展
extension AlertView: UIGestureRecognizerDelegate
// Only handle this for the background tap gesture
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool
guard gestureRecognizer == backgroundViewTapGesture, let backgroundView = gestureRecognizer.view, let alertView = self.alertContentView else
return true
let touchLocation = touch.location(in: backgroundView)
return !alertView.frame.contains(touchLocation)
【讨论】:
【参考方案4】:在斯威夫特中:
public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool
let locationInView = touch.location(in: mainView)
if debugOptionsView.isHidden
return true
return !debugOptionsView.frame.contains(locationInView)
【讨论】:
以上是关于如何防止点击子视图触发父视图上的 UITapGestureRecognizer?的主要内容,如果未能解决你的问题,请参考以下文章
如何在被父视图部分裁剪的子视图上触发 UITapGestureRecognizer?
防止子视图上的 UITapGestureRecognizer