具有 UITapGestureRecognizer 的视图内的 UIButton
我有一个 UITapGestureRecognizer
的视图。因此,当我点击视图时,另一个视图会出现在该视图上方。这个新视图有三个按钮。当我现在按下这些按钮之一时,我不会得到按钮操作,我只会得到点击手势操作。所以我无法再使用这些按钮了。我该怎么做才能将事件传递到这些按钮?奇怪的是按钮仍然突出显示。
我不能在收到 UITapGestureRecognizer 的点击后将其删除。因为有了它,新视图也可以被删除。意味着我想要一个类似全屏视频控件的行为。
I have view with a UITapGestureRecognizer
. So when I tap on the view another view appears above this view. This new view has three buttons. When I now press on one of these buttons I don't get the buttons action, I only get the tap gesture action. So I'm not able to use these buttons anymore. What can I do to get the events through to these buttons? The weird thing is that the buttons still get highlighted.
I can't just remove the UITapGestureRecognizer after I received it's tap. Because with it the new view can also be removed. Means I want a behavior like the fullscreen vide controls.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
您可以将控制器或视图(以创建手势识别器的那个为准)设置为 UITapGestureRecognizer 的委托。然后在委托中您可以实现
-gestureRecognizer:shouldReceiveTouch:
。在您的实现中,您可以测试触摸是否属于您的新子视图,如果属于,则指示手势识别器忽略它。像下面这样:You can set your controller or view (whichever creates the gesture recognizer) as the delegate of the
UITapGestureRecognizer
. Then in the delegate you can implement-gestureRecognizer:shouldReceiveTouch:
. In your implementation you can test if the touch belongs to your new subview, and if it does, instruct the gesture recognizer to ignore it. Something like the following:作为凯西对凯文巴拉德答案的后续行动:
这基本上使所有用户输入类型的控件(如按钮、滑块等)都可以工作
As a follow up to Casey's follow up to Kevin Ballard's answer:
This basically makes all user input types of controls like buttons, sliders, etc. work
在这里找到了这个答案:链接
您还可以使用
which防止点击识别器成为唯一一个捕获所有点击
更新 的人- Michael 提到了描述此属性的文档链接:cancelsTouchesInView
Found this answer here: link
You can also use
Which prevents the tap recognizer to be the only one to catch all the taps
UPDATE - Michael mentioned the link to the documentation describing this property: cancelsTouchesInView
作为 Kevin Ballard 回答的后续,我遇到了同样的问题并最终使用了这段代码:
它具有相同的效果,但这适用于任何视图深度的任何 UIButton(我的 UIButton 是多个视图深度,而 UIGestureRecognizer 的委托没有)没有参考它。)
As a follow up to Kevin Ballard's answer, I had this same problem and ended up using this code:
It has the same effect but this will work on any UIButton at any view depth (my UIButton was several views deep and the UIGestureRecognizer's delegate didn't have a reference to it.)
在 iOS 6.0 及更高版本中,默认控制操作可防止手势识别器行为重叠。例如,按钮的默认操作是单击。如果您将单击手势识别器附加到按钮的父视图,并且用户点击该按钮,则该按钮的操作方法将接收触摸事件而不是手势识别器。这仅适用于与控件的默认操作重叠的手势识别,其中包括:.....
来自 Apple 的 API 文档
In iOS 6.0 and later, default control actions prevent overlapping gesture recognizer behavior. For example, the default action for a button is a single tap. If you have a single tap gesture recognizer attached to a button’s parent view, and the user taps the button, then the button’s action method receives the touch event instead of the gesture recognizer. This applies only to gesture recognition that overlaps the default action for a control, which includes:.....
From Apple's API doc
这些答案并不完整。我必须阅读多篇关于如何使用此布尔运算的文章。
在您的 *.h 文件中添加此
在您的 *.m 文件中添加此
These answers were incomplete. I had to read multiple posts as to how to use this boolean operation.
In your *.h file add this
In your *.m file add this
从此处找到了另一种方法。它检测触摸是否在每个按钮内部。
(1) pointInside:withEvent:
(2) locationInView:
Found another way to do it from here. It detects the touch whether inside each button or not.
(1) pointInside:withEvent:
(2) locationInView:
带有 Tapgesture 的超级视图上的Swift 5
按钮
在我的例子中,实现 hitTest 对我有用。我有带有按钮的集合视图
此方法通过调用每个子视图的 point(inside:with:) 方法来遍历视图层次结构,以确定哪个子视图应该接收触摸事件。如果 point(inside:with:) 返回 true,则类似地遍历子视图的层次结构,直到找到包含指定点的最前面的视图。
Swift 5
Button on superview with tapgesture
In my case implementing hitTest worked for me. I had collection view with button
This method traverses the view hierarchy by calling the
point(inside:with:)
method of each subview to determine which subview should receive a touch event. Ifpoint(inside:with:)
returns true, then the subview’s hierarchy is similarly traversed until the frontmost view containing the specified point is found.这是对我有用的 Lily Ballard 的答案 的 Swift 版本:
Here's the Swift version of Lily Ballard's answer that worked for me:
您可以通过设置以下布尔值来阻止 UITapGestureRecognizer 取消其他事件(例如点击按钮):
You can stop the UITapGestureRecognizer from cancelling other events (such as the tap on your button) by setting the following boolean:
如果您的场景是这样的:
您有一个简单的视图和一些 UIButtons、UITextField 控件作为子视图添加到该视图。现在,当您触摸视图上除控件(您添加的子视图)之外的任何其他位置时,您想关闭键盘
那么解决方案是:
将以下方法添加到您的 XYZViewController.m(其中有您的视图)
If your scenario is like this:
You have a simple view and some UIButtons,UITextField controls added as subviews to that view. Now you want to dismiss the keyboard when you touch anywhere else on the view except on the controls(subviews you added)
Then Solution is:
Add the following method to your XYZViewController.m(which has your view)
优化cdasher的答案,你得到
Optimizing cdasher's answer, you get
另一种选择是将
UITapGestureRecognizer
附加到UIButton
下方的某个子视图,而不是附加到主 viewController 视图假设您有一个子视图
mySubView
> 并且按钮堆叠在它上面,但不属于它。然后你将创建你的 tapGestureRecognizer 如下Another option is to attach the
UITapGestureRecognizer
to some subView that is underneath theUIButton
, instead of attaching to your main viewController viewSay you have a subView
mySubView
and teh buttons are stacked over it, but do not belong to it. Then you will create your tapGestureRecognizer as follows