你将如何重新实现UIControl?它如何适应响应者链?

时间:2014-10-18 21:33:10

标签: ios objective-c swift uikit

如果我要重写UIKit,我该如何实现UIControl?

我在将UIControl纳入我对触摸处理的概念性理解方面遇到了一些麻烦。响应者链。具体来说,我对谁负责调用UIControl的begincontinueendTrackingWithTouch:withEvent来电感到困惑。

我天真的解释是,UIControl负责处理触摸事件,如touchesBegan:和相关方法中的UIResponder的任何其他子类。然而,这将变得复杂,因为触摸事件仍然与首先处理它的视图相关联,并且这将产生这样的情况:源自按钮但在屏幕上作为平移继续的触摸将继续由该按钮处理,这似乎违反直觉。在这种情况下,我可以想象按钮可以开始将这些触摸事件转发到其超级视图,但这看起来很难看。由于UIControlEvents(例如touchUpInside)表明正在其他地方处理触摸并且仅向UIControl通知谨慎事件,所以这一切都会有点混乱。

我最好的猜测是,在查看视图层次以找到响应者时,UIControls的处理方式不同,并且最顶层的非控制响应者检查其任何子视图都是UIControls,然后调用正确的根据需要的方法,但这似乎有点奇怪。

有人对这一点有任何指导或澄清吗?我对文档进行了一些挖掘,但没有发现任何明确的内容。

1 个答案:

答案 0 :(得分:1)

UIControl是UIView的子类,因此它可以检测用户交互,并使用目标操作模式调用对象/目标上的某些方法/操作。

正如你所说,用Apple方式:"An Event Travels Along a Specific Path Looking for an Object to Handle It"

UIControl的基本工作流程:

  • UIControl检测基本事件(UIControlEventTouchDownUIControlEventTouchCancel ...),该事件由连锁响应程序工作流处理。

  • addTarget:action:forControlEvents:告诉UIControl在目标上调用事件类型参数的操作。

  • 当eventType和目标匹配时,操作将会触发。

修改

UIControl只是一个为实现它的对象提供目标/操作模式行为的接口。

所以真正发生的是,当你触摸屏幕时,会创建一个基本的UIEvent 时间戳,类型(触摸,运动或远程控制)和子类型。

iOS会在此事件中收集与此事件相关的所有UITouch(一个UITouch =一个手指触摸操作)。 UITouch包含触摸发生的UIViewUIWindow以及其他内容。

UIEvent有三个功能:

  • allTouches():返回NSSet UITouch
  • touchesForView(aView):对于特定NSSet
  • ,返回UITouch UIView
  • touchesForWindow(aWindow):对于特定NSSet
  • ,返回UITouch UIWindow

根据我的理解,当事件被触发时,系统会将其发送到您的UIApplication,并将事件发送到FirstResponderChain工作流程。

所以,我认为当在View Hierarchy中关闭时,它会检查touchesForView方法是否返回一些东西,如果它返回了某些内容,那么它会调用实现UIView上的相应方法{ {1}}),因此可以调用UIResponder。它继续前进。