将触摸事件传递给相应的同级 UIView

发布于 2024-09-27 20:03:58 字数 341 浏览 3 评论 0原文

我试图在父 UIView 的覆盖层中使用 touchesBegan 处理触摸事件,但也允许触摸输入传递到同级 UIView是在下面。我预计会有一些直接的方法来处理触摸事件,然后说“现在将其发送给下一个响应者,就好像这个响应者不存在一样”,但我能找到的只是 nextResponder 方法似乎将父级返回给我的覆盖视图。然后,该父级并没有真正将其传递到该覆盖视图的下一个同级,因此我不确定如何执行看似简单的任务,该任务通常通过触摸回调来完成,该回调获取 True 或 False 返回值来告诉它是否继续处理小部件层次结构。

我错过了一些明显的东西吗?

I'm trying to handle touch events with touchesBegan in an overlay to a parent UIView but also allow the touch input to pass through to sibling UIViews underneath. I expected there would be some straight-forward way to process a touch event and then say "now send it to the next responder as if this one didn't exist", but all I can find is the nextResponder method which appears to be giving back the parent to my overlay view. That parent is then not really passing it onto the next sibling of that overlay view so I'm stuck uncertain how to do what seems like a simple task that is usually accomplished with a touch callback that gets a True or False return value to tell it whether to keep processing down the widget hierarchy.

Am I missing something obvious?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你的笑 2024-10-04 20:03:58

迟到的答案,但我认为你最好覆盖 hitTest:withEvent: 而不是 touchesBegan。在我看来,touchesBegan 是一个相当“高级”的方法,它只是做一件简单的事情,所以如果事件进一步传播,你就无法在该级别进行更改。正确的位置是 hitTest:withEvent:

另请查看这个答案有关这一点的更多详细信息。

Late answer, but I think you would be better off overriding hitTest:withEvent: instead of touchesBegan. It seems to me that touchesBegan is a pretty "high-level" method that is there to just do a simple thing, so you cannot alter at that level if the event if propagated further. The right place to do that is hitTest:withEvent:.

Also have a look at this S.O. answer for more details about this point.

神爱温柔 2024-10-04 20:03:58

我了解您正在寻找的所需行为 Joey - 我在 API 中没有找到支持这种具有同级视图的自动消息传递链行为的内容。

我最初在下面写的是关于仅通知父 UIView 有关触摸的信息。这仍然适用,但我相信您需要更进一步,让父 UIView 使用 Sergio 在与覆盖层同级的每个子视图上描述的命中测试技术,并让父 UIView 手动调用“do在每个通过命中测试的子视图上使用“something”方法。每个同级视图都可以返回一个 BOOL 值,指示是否中止通知其他同级视图或继续该链。

如果您发现自己经常使用此模式,请考虑在 UIView 上添加一个类别方法,该方法封装了命中测试并要求视图执行选择器。

我的原始答案

通过一些手动工作,您可以自己将其连接起来。我必须这样做,它对我有用,因为我有一个经常重复的用例(按钮上的覆盖视图),在其中创建一些自定义类是有意义的。如果您的情况类似,那么其中一种技术就足够了。

选项 1:
如果叠加层除了看起来漂亮之外不需要执行任何操作,请使用 userInteractionEnabled = NO 选择完全脱离接触处理。这将使触摸事件转到它的父 UIView(它是覆盖的那个)。

选项 2:
让覆盖层吸收触摸事件(默认情况下会如此),然后在父 UIView 上调用一个方法,指示识别出触摸或特定手势,这就是它的内容。这样,即使其他人进行了拦截,覆盖层后面的 UIView 仍然可以对触摸识别进行操作。

使用选项 2,它更适合简单的 UIControlEvent 类型,例如 UIControlEventTouchDownUIControlEventTouchUpInside。在我的例子中(一个自定义 UIButton 子类,其顶部有一个自定义覆盖视图),我将按钮上的触摸按下和触摸向上事件连接到两个单独的方法。如果按钮本身发生触碰或触碰内部事件,则会触发这些事件。但是,如果我需要模拟按下按钮的情况,它们也是我可以从覆盖视图调用的钩子。

根据您的需要,您可以在覆盖层与其父 UIView 之间有一个已知的协议,或者只是让覆盖层非正式地测试 UIView,在调用 performSelector:respondsToSelector: 检查> 在其上使用您想要调用的自定义方法,如果 UIView 没有被覆盖层覆盖,该方法将自动触发。

I understand the desired behavior you're looking for Joey - I haven't found something in the API that supports this automatic messaging-up-the-chain behavior with sibling views.

What I originally wrote below was with respect to just informing a parent UIView about a touch. This still applies, but I believe you need to take it a step further and have the parent UIView use the hit testing technique that Sergio described on each of it's subviews that are siblings to the overlay, and have the parent UIView manually invoke a "do something" method on each of it's subviews that pass the hit test. Each of those sibling views can return a BOOL value on whether to abort informing other siblings or continue the chain.

If you find yourself using this pattern a lot, consider adding a category method on UIView that encapsulates the hit testing and asking views to perform a selector.

My Original Answer

With a little bit of manual work, you can wire this together yourself. I've had to do this, and it worked for me, because I had an oft-repeated use case (an overlay view on a button), where it made sense to create some custom classes. If your situation is similar, one of these techniques will suffice.

Option 1:
If the overlay doesn't need to do anything but look pretty, have it opt out of touch handling completely with userInteractionEnabled = NO. This will make it so that the touch event goes to it's parent UIView (the one it is an overlay to).

Option 2:
Have the overlay absorb the touch event (as it would by default), and then invoke a method on the parent UIView indicating that a touch or certain gesture was recognized, and here's what it is. This way, the UIView behind the overlay still gets to act on the touch recognition, even if someone else did the interception.

With Option 2, it's more a fit for simple UIControlEvent types, like UIControlEventTouchDown and UIControlEventTouchUpInside. In my case (a custom UIButton subclass with a custom overlay view on top of it), I'll wire touch down and touch up events on the button to two separate methods. These fire if a touch down or touch up inside event occurs on the button itself. But, they are also hooks I can invoke from the overlay view if I need to simulate that a button press occurred.

Depending on your needs, you could have a known protocol between the overlay and it's parent UIView or just have the overlay test the UIView informally, with a respondsToSelector: check before invoking performSelector: on it with the custom method you want called that would have fired automatically if the UIView wasn't covered by an overlay.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文