你将如何重新实现 UIControl?它如何适应响应者链?
Posted
技术标签:
【中文标题】你将如何重新实现 UIControl?它如何适应响应者链?【英文标题】:How would you reimplement UIControl? How does it fit into the responder chain? 【发布时间】:2014-10-18 21:33:10 【问题描述】:如果我要重写 UIKit,我将如何实现 UIControl?
我在将 UIControl 纳入我对触摸处理和响应程序链的概念理解中遇到了一些麻烦。具体来说,我对谁负责调用 UIControl 的begin
、continue
和endTrackingWithTouch:withEvent
调用感到困惑。
我的天真解释是 UIControl 负责处理触摸事件,就像 UIResponder 的任何其他子类一样,在touchesBegan:
和相关方法中。然而,这会变得复杂,因为触摸事件仍然与首先处理它的视图相关联,这将产生一种情况,即源自按钮但继续在屏幕上平移的触摸将继续由该按钮处理,这似乎违反直觉。我可以想象在这种情况下按钮可以开始将这些触摸事件转发到它的超级视图,但这看起来很难看。由于 UIControlEvents,例如 touchUpInside,这一切都变得有些混乱,这表明触摸正在其他地方进行处理,而 UIControl 仅被通知谨慎事件。
在这里,我最好的猜测是,当遍历视图层次结构以查找响应者时,UIControls 的处理方式不同,并且对其任何子视图的最顶层的非控制响应者检查是 UIControls,然后调用正确的方法根据需要,但这似乎也有点奇怪。
有人对此有任何指导或澄清吗?我已经仔细研究了文档,但没有发现任何明确的内容。
【问题讨论】:
【参考方案1】:UIControl
是 UIView 的子类,因此它可以检测用户交互,并使用目标-动作模式来调用对象/目标上的一些方法/动作。
如你所说,以苹果方式:"An Event Travels Along a Specific Path Looking for an Object to Handle It"
UIControl
的基本工作流程:
UIControl
检测到基本事件(UIControlEventTouchDown
、UIControlEventTouchCancel
...),该事件由链 Responder 工作流处理。
addTarget:action:forControlEvents:
告诉 UIControl
为事件类型参数调用目标上的操作。
当 eventType 和 target 匹配时,动作就会触发。
编辑
UIControl
只是一个接口,为实现它的对象提供目标/动作模式行为。
所以真正发生的是,当您触摸屏幕时,会创建一个基本的 UIEvent 时间戳、类型(Touches、Motion 或 RemoteControl)和子类型。
ios 会将与此事件相关的所有UITouch
收集到此事件中(一个UITouch
= 一个手指触摸动作)。 UITouch 包含发生触摸的UIView
和UIWindow
以及其他内容。
UIEvent 中有三个函数:
allTouches()
:返回 NSSet
的 UITouch
touchesForView(aView)
:对于特定的UIView
,返回 NSSet
的 UITouch
touchesForWindow(aWindow)
:对于特定的UIWindow
,返回 NSSet
of UITouch
据我了解,当 Event 被触发时,系统会将其发送到您的UIApplication
,并将该事件发送到 FirstResponderChain 工作流。
所以,我认为当视图层次结构下降时,它会检查 touchesForView
method 是否返回一些东西,如果它返回一些东西,那么它会在实现 UIResponder
的 UIView
上调用适当的方法,所以它可以调用touchesBegan:withEvent:
例如。否则它会继续。
【讨论】:
我想我没有清楚地说明这个问题。 UIControl 如何和磨损检测事件?它在它自己的 touchesBegan/touchesMoved 方法中吗?好像不是这样的。 我很欣赏编辑。这一切都很好,但它并不能真正回答问题,这与谁实际负责调用各种 UIControl 事件有关。 调用者是系统,所以如果你想真正知道是谁在调用它,你必须用你的调试器深入研究 UIKit。我最近读了[这篇文章] (petersteinberger.com/blog/2014/…),它解释了如何调配一些 UIResponder 方法,因此它更深入地介绍了触摸转发,所以也许它可以帮助你。 啊,看起来很整洁。我也一直在阅读 chameleon 的源代码,它是 UIKit 大部分的开放式重新实现:github.com/BigZaphod/Chameleon/tree/master/UIKit以上是关于你将如何重新实现 UIControl?它如何适应响应者链?的主要内容,如果未能解决你的问题,请参考以下文章
如何将 UIControl 从 iPhone xib 重用到 iPad xib
你将如何实现 [UIViewController presentModalViewController]?