Allow UIScrollView and its subviews to both respond to a touch(允许 UIScrollView 及其子视图都响应触摸)
问题描述
我希望我的 UIScrollView 及其子视图都能接收子视图内的所有触摸事件.每个人都可以以自己的方式做出回应.
I want both my UIScrollView and its subviews to receive all touch events inside the subview. Each can respond in its own way.
或者,如果将点击手势转发到子视图,一切都会好起来的.
Alternatively, if tap gestures were forwarded to subviews, all would be well.
很多人都在这个一般领域苦苦挣扎.以下是众多相关问题中的几个:
A lot of people are struggling in this general area. Here are a few of the many related questions:
UIScrollView 如何从其子视图中窃取触摸
如何从 UIScrollView 窃取触摸?
如何在 UIScrollView 中取消滚动
顺便说一句,如果我在滚动视图中覆盖 hitTest:withEvent:,只要 userInteractionEnabled 为 YES,我就会看到触摸.但这并不能真正解决我的问题,因为:
Incidentally, if I override hitTest:withEvent: in the scroll view, I do see the touches as long as userInteractionEnabled is YES. But that doesn't really solve my problem, because:
1) 到那时,我不知道是不是水龙头.
2) 有时我需要将 userInteractionEnabled 设置为 NO.
1) At that point, I don't know if it's a tap or not.
2) Sometimes I need to set userInteractionEnabled to NO.
为了澄清,是的,我想将水龙头与平底锅区别对待.点击应该由子视图处理.平底锅可以通过滚动视图以通常的方式处理.
To clarify, yes, I want to treat taps differently from pans. Taps should be handled by subviews. Pans can be handled by the scroll view in the usual way.
推荐答案
首先,免责声明.如果在 UIScrollView
上将 userInteractionEnabled
设置为 NO
,则不会将触摸事件传递给子视图.据我所知,除了一个例外:在 UIScrollView
的父视图上拦截触摸事件,并将这些事件专门传递给 UIScrollView
.不过,老实说,我不知道你为什么要这样做.如果你想禁用特定的 UIScrollView 功能(比如......好吧,滚动),你可以很容易地做到这一点,而无需禁用 UserInteraction.
First, a disclaimer. If you set userInteractionEnabled
to NO
on the UIScrollView
, no touch events will be passed to the subviews. So far as I'm aware, there's no way around that with one exception: intercept touch events on the superview of the UIScrollView
, and specifically pass those events to the subviews of UIScrollView
. To be honest, though, I don't know why you would want to do this. If you're wanting to disable specific UIScrollView functionality (like...well, scrolling) you can do that easily enough without disabling UserInteraction.
如果我理解您的问题,您需要 UIScrollView 处理点击事件 并传递给子视图吗?无论如何(无论手势是什么),我认为您正在寻找的是协议方法 gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: 在协议 UIGestureRecognizerDelegate
中.在您的子视图中,无论您拥有什么手势识别器,都在手势识别器上设置一个委托(可能是首先设置 UIGestureReconginzer
的任何类).覆盖上述方法并返回 YES
.现在,该手势将与任何其他可能窃取"该手势的识别器一起被识别(在您的情况下,点击).使用此方法,您甚至可以微调您的代码以仅向子视图发送某些类型的手势或仅在某些情况下发送手势.它给了你很多控制权.请务必阅读该方法,尤其是这一部分:
If I understand your question, you need tap events to be processed by the UIScrollView and passed to the subviews? In any case (whatever the gesture is), I think what you're looking for is the protocol method gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: in the protocol UIGestureRecognizerDelegate
. In your subviews, whatever gesture recognizers you have, set a delegate (probably whatever class is setting the UIGestureReconginzer
in the first place) on the gesture recognizer. Override the above method and return YES
. Now, this gesture will be recognized along with any other recognizers that might have 'stolen' the gesture (in your case, a tap). Using this method you can even fine tune your code to only send certain kinds of gestures to the subviews or send the gesture only in certain situations. It gives you a lot of control. Just be sure to read about the method, especially this part:
识别手势时调用该方法手势识别器或其他手势识别器会阻止其他手势识别器识别其手势.注意返回 YES 保证允许同时识别;另一方面,返回 NO 并不能保证防止同时识别,因为其他手势识别器的委托可能会返回 YES.
This method is called when recognition of a gesture by either gestureRecognizer or otherGestureRecognizer would block the other gesture recognizer from recognizing its gesture. Note that returning YES is guaranteed to allow simultaneous recognition; returning NO, on the other hand, is not guaranteed to prevent simultaneous recognition because the other gesture recognizer's delegate may return YES.
当然,有一点需要注意:这只适用于手势识别器.因此,如果您尝试使用 touchesBegan:
、touchesEnded
等来处理触摸,您可能仍然会遇到问题.当然,您可以使用 hitTest:
将原始触摸事件发送到子视图,但为什么呢?当您可以将 UIGestureRecognizer
附加到视图并免费获得所有这些功能时,为什么要使用 UIView
中的这些方法来处理事件?如果您需要以标准 UIGestureRecognizer
无法提供的方式处理触摸,subclass UIGestureRecognizer
并在那里处理触摸.这样您就可以获得 UIGestureRecognizer
的所有功能以及您自己的自定义触摸处理.我真的认为 Apple 打算让 UIGestureRecognizer
替换开发人员在 UIView
上使用的大部分(如果不是全部)自定义触摸处理代码.它允许代码重用,并且在减轻哪些代码处理哪些触摸事件时更容易处理.
Of course, there's a caveat: This only applies to gesture recognizers. So you may still have problems if you're trying to use touchesBegan:
, touchesEnded
, etc to process the touches. You can, of course, use hitTest:
to send raw touch events on to the subviews, but why? Why process the events using those methods in UIView
, when you can attach a UIGestureRecognizer
to a view and get all of that functionality for free? If you need touches processed in a way that no standard UIGestureRecognizer
can provide, subclass UIGestureRecognizer
and process the touches there. That way you get all the the functionality of a UIGestureRecognizer
along with your own custom touch processing. I really think Apple intended for UIGestureRecognizer
to replace most (if not all) of the custom touch processing code that developers use on UIView
. It allows for code-reuse and it's a lot easier to deal with when mitigating what code processes what touch event.
这篇关于允许 UIScrollView 及其子视图都响应触摸的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:允许 UIScrollView 及其子视图都响应触摸
基础教程推荐
- 如何让对象对 Cocos2D 中的触摸做出反应? 2022-01-01
- android 应用程序已发布,但在 google play 中找不到 2022-01-01
- UIWebView 委托方法 shouldStartLoadWithRequest:在 WKWebView 中等效? 2022-01-01
- 如何在 UIImageView 中异步加载图像? 2022-01-01
- 在 gmail 中为 ios 应用程序检索朋友的朋友 2022-01-01
- 如何在没有IB的情况下将2个按钮添加到右侧的UINavigationbar? 2022-01-01
- 当从同一个组件调用时,两个 IBAction 触发的顺序是什么? 2022-01-01
- Kivy Buildozer 无法构建 apk,命令失败:./distribute.sh -m “kivy"d 2022-01-01
- Android:对话框关闭而不调用关闭 2022-01-01
- 如何在 iPhone 上显示来自 API 的 HTML 文本? 2022-01-01