UITouch& UIEvents:与框架战斗?
假设一个视图有 4 个子视图,这些子视图彼此相邻但不重叠。 让我们称它们为 view#1 ... view#4
所有 5 个这样的视图都是我自己的 UIView 子类(是的,我读过:事件处理以及iOS 事件指南 和这个SO问题和这个one,尚未回答)
当用户触摸其中之一,UIKit 会对其进行“hiTests”并将后续事件传递到该视图:view#1
即使手指移到 view#1 之外(例如 view#3)。
即使此“拖动”现在位于 view#3 上方,view#1 仍会接收到 TouchMoved,但 view#3 不会接收到任何内容。
我希望 view#3 开始回复触摸。也许是我自己的“touchedEntered”,可能还有 view#1 上的“touchesExited”。
我该怎么办呢?
我可以看到两种方法。
- 回避问题并在父级中进行所有触摸处理 每当我检测到touchesMoved超出view#1边界时查看,或者
- 转移到父视图告诉它“重新调度”。不太 不过,很清楚这种重新调度将如何进行。
对于解决方案#2,我感到困惑的不是转发本身,而是如何找到我想要转发到的 UIVIew。我显然可以循环父级子视图,直到我找到一个其边界/框架包含触摸的视图,但我想知道我是否错过了苹果已经提供的东西,但我无法解决这个问题。
有什么想法吗?
Imagine a view with, say, 4 subviews, next to each other but non overlapping.
Let's call them view#1 ... view#4
All 5 such views are my own UIView subclasses (yes, I've read: Event Handling as well as iOS Event Guide and this SO question and this one, not answered yet)
When the user touches one of them, UIKit "hiTests" it and delivers subsequent events to that view: view#1
Even when the finger goes outside view#1, over say view#3.
Even if this "drag" is now over view#3, view#1 still receives touchesMoved, but view#3 receives nothing.
I want view#3 to start replying to the touches. Maybe with a "touchedEntered" of my own, together with possibly a "touchesExited" on view#1.
How would I go about this?
I can see two approaches.
- side step the problem and do all the touch handling in the parent
view whenever I detect a touchesMoved outside of view#1 bounds or, - transfer to the parent view telling it to "redispatch". Not very
clear how such redispatching would work, though.
For solution #2 where I am getting confused is not about the forwarding per se, but how to find the UIVIew I want to forward to. I can obviously loop through the parent subviews until I find one whose bounds/frame contain the touch, but I am wondering if I am missing something, that Apple would have already provided but I cannot relate to this problem.
Any idea?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我已经这样做了,但我使用了 CALayers 而不是子 UIView。这样,就不用担心子视图捕获/重新分派事件到父 UIView。您可能无法做到这一点,但它确实简化了事情。我的解决方案倾向于大量使用 CGRectContainsPoint() 。
I have done this, but I used CALayers instead of sub-UIViews. That way, there is no worries about the subviews catching/redispatching events to the parent UIView. You might not be able to do that, but it does simplify things. My solution tended to use
CGRectContainsPoint()
a lot.您可能想再次阅读事件处理,因为它非常接近回答您的问题:
鉴于此,如果您想实现让不同的视图对用户的手指越过它们做出反应的目标,并且如果您想在 UIView 提供的触摸处理机制内完成此操作,您应该采用第一种方法:父视图处理触摸。父级可以使用
-hitTest:withEvent:
或-pointInside:withEvent:
因为它正在跟踪触摸以确定触摸是否在子视图之一中,如果是,则可以发送适当的消息。You may want to read Event Handling again, as it comes pretty close to answering your question:
Given that, if you want to accomplish your goal of having different views react to the user's finger crossing over them, and if you want to do it within the touch-handling mechanism provided by UIView, you should go with your first approach: have the parent view handle the touch. The parent can use
-hitTest:withEvent:
or-pointInside:withEvent:
as it's tracking a touch to determine if the touch is in one of the subviews, and if so can send an appropriate message.