UIGestureRecognizer 阻止子视图处理触摸事件
我正在尝试弄清楚如何以正确的方式完成此操作。我试图描述这种情况:
我正在添加 UITableView
作为 UIView 的子视图
。 UIView
响应点击和 pinchGestureRecognizer
,但是当这样做时,tableview 停止对这两个手势做出反应(它仍然对滑动做出反应)。
我已经使它与以下代码一起工作,但这显然不是一个好的解决方案,我确信有更好的方法。这被放入 UIView
(超级视图)中:
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
if([super hitTest:point withEvent:event] == self) {
for (id gesture in self.gestureRecognizers) {
[gesture setEnabled:YES];
}
return self;
}
for (id gesture in self.gestureRecognizers) {
[gesture setEnabled:NO];
}
return [self.subviews lastObject];
}
I'm trying to figure out how this is done the right way. I've tried to depict the situation:
I'm adding a UITableView
as a subview of a UIView
. The UIView
responds to a tap- and pinchGestureRecognizer
, but when doing so, the tableview stops reacting to those two gestures (it still reacts to swipes).
I've made it work with the following code, but it's obviously not a nice solution and I'm sure there is a better way. This is put in the UIView
(the superview):
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
if([super hitTest:point withEvent:event] == self) {
for (id gesture in self.gestureRecognizers) {
[gesture setEnabled:YES];
}
return self;
}
for (id gesture in self.gestureRecognizers) {
[gesture setEnabled:NO];
}
return [self.subviews lastObject];
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
我有一个非常类似的问题,并在这个问题中找到了我的解决方案 。总之,将自己设置为
UIGestureRecognizer
的委托,然后在允许识别器处理触摸之前检查目标视图。相关的委托方法是:I had a very similar problem and found my solution in this SO question. In summary, set yourself as the delegate for your
UIGestureRecognizer
and then check the targeted view before allowing your recognizer to process the touch. The relevant delegate method is:阻止子视图的触摸事件是默认行为。您可以更改此行为:
The blocking of touch events to subviews is the default behaviour. You can change this behaviour:
我正在显示一个具有自己的表格视图的下拉子视图。因此,
touch.view
有时会返回类似UITableViewCell
的类。我必须遍历超类以确保它是我认为的子类:I was displaying a dropdown subview that had its own tableview. As a result, the
touch.view
would sometimes return classes likeUITableViewCell
. I had to step through the superclass(es) to ensure it was the subclass I thought it was:以 @Pin Shih Wang 答案为基础。我们忽略除包含点击手势识别器的视图上的点击之外的所有点击。正如我们设置的
tapGestureRecognizer.cancelsTouchesInView = false
一样,所有点击都会转发到视图层次结构。这是 Swift3/4 中的代码:Building on @Pin Shih Wang answer. We ignore all taps other than those on the view containing the tap gesture recognizer. All taps are forwarded to the view hierarchy as normal as we've set
tapGestureRecognizer.cancelsTouchesInView = false
. Here is the code in Swift3/4:一种可能性是子类化您的手势识别器(如果您还没有)并覆盖
-touchesBegan:withEvent:
,以便确定每次触摸是否在排除的子视图中开始并调用-ignoreTouch: forEvent:
对于该触摸(如果有)。显然,您还需要添加一个属性来跟踪排除的子视图,或者更好的是,跟踪排除的子视图的数组。
One possibility is to subclass your gesture recognizer (if you haven't already) and override
-touchesBegan:withEvent:
such that it determines whether each touch began in an excluded subview and calls-ignoreTouch:forEvent:
for that touch if it did.Obviously, you'll also need to add a property to keep track of the excluded subview, or perhaps better, an array of excluded subviews.
不继承任何类也是可以的。
你可以在手势的回调选择器中检查gestureRecognizers
如果view.gestureRecognizers不包含你的gestureRecognizer,
,只需忽略它,例如
在这里检查view.gestureRecognizers
It is possible to do without inherit any class.
you can check gestureRecognizers in gesture's callback selector
if view.gestureRecognizers not contains your gestureRecognizer,just ignore it
for example
check view.gestureRecognizers here
我创建了一个 UIGestureRecognizer 子类,旨在阻止附加到特定视图的超级视图的所有手势识别器。
这是我的 WEPopover 项目的一部分。您可以在此处找到它。
I created a UIGestureRecognizer subclass designed for blocking all gesture recognizers attached to a superviews of a specific view.
It's part of my WEPopover project. You can find it here.
为parentView的所有识别器实现一个委托,并将gestureRecognizer方法放在负责同时触发识别器的委托中:
如果你想让子识别器被触发而不是父识别器,你可以使用fail方法:
https://developer.apple.com/reference/uikit/uigesturerecognizerdelegate
implement a delegate for all the recognizers of the parentView and put the gestureRecognizer method in the delegate that is responsible for simultaneous triggering of recognizers:
U can use the fail methods if u want to make the children be triggered but not the parent recognizers:
https://developer.apple.com/reference/uikit/uigesturerecognizerdelegate
我也在做一个弹出窗口,这就是我所做的
I was also doing a popover and this is how I did it
您可以将其关闭然后打开...在我的代码中,我做了类似的事情,因为我需要在键盘未显示时将其关闭,您可以将其应用到您的情况:
调用这是 viewdidload 等:
然后创建两种方法:
其作用是禁用水龙头。我必须将 tap 转换为实例变量并在 dealloc 中释放它。
You can turn it off and on.... in my code i did something like this as i needed to turn it off when the keyboard was not showing, you can apply it to your situation:
call this is viewdidload etc:
then create the two methods:
What this does is disables the tap. I had to turn tap into a instance variable and release it in dealloc though.