首页 >> 大全

响应方法和响应事件传递

2023-11-09 大全 27 作者:考证青年

目录 响应方法和响应事件传递事件处理机制的应用 使用Hit-Test来扩大点击范围处理兄弟控件的事件 事件处理机制在系统控件中 参考资料

事件的种类

其中最常见的就是触摸事件,文章后续都已触摸事件为例来进行讲解。

事件响应链

首先iOS只有集成了的对象,才有资格成为事件响应者。常见的时间响应者对象包含、、、等组件。其次,在App中的组件是一个树状结构,在每个单例下可能会有多个,一个下有可能有多个,以此类推,因此iOS中,会形成一个事件响应链的形态。

事件响应者 如何成为事件响应者

只要是继承了的对象都可以成为事件响应者,但是一个事件产生之后第一件是是要找出这个事件的第一响应者。找出第一响应者的方法叫做hit-test。

Hit-Test

可以成为第一响应者的对象除了需要继承以外,还有一个更严格的条件,除对象以外,其余的对象如果想要成为第一响应者一定要继承,只有才有资格成为第一响应者。

类中包含两个方法

- (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event;   // recursively calls -pointInside:withEvent:. point is in the receiver's coordinate system
- (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event;   // default returns YES if point is in bounds

第二个::方法仅在::方法中才会调用

找到事件的第一响应者的流程如下:

系统在检测到用户的触摸事件后,将事件以及时间的参数(比如触摸点的坐标)等数据作为参数,向当前的单例对象发送消息。单例收到之后,会依次调用显示的对象的::方法,如果方法返回了一个对象,则这个对象就是第一响应者,如果返回为空,则对象就是第一响应者。在::方法中,会调用::方法来判断该事件是否属于当前对象,如果不属于,就直接返回空。如果属于当前对象,则会继续遍历其,调用每个的::方法。如果所有该方法都返回了空,那么就返回当前对象为第一事件响应者。以此类递归找到最终的子组件,这样就可以找到第一事件响应者了。

_事件传递和事件响应_响应传递事件方法包括

响应方法和响应事件传递

类中包含如下的方法:

// 下一个响应者
open var next: UIResponder? { get }// 第一响应者相关方法
open var canBecomeFirstResponder: Bool { get } // default is NO
open func becomeFirstResponder() -> Bool
open var canResignFirstResponder: Bool { get } // default is YES
open func resignFirstResponder() -> Bool
open var isFirstResponder: Bool { get }// 触摸事件
open func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
open func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?)
open func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?)
open func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?)
@available(iOS 9.1, *)
open func touchesEstimatedPropertiesUpdated(_ touches: Set<UITouch>)// 运动事件
open func motionBegan(_ motion: UIEvent.EventSubtype, with event: UIEvent?)
open func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?)
open func motionCancelled(_ motion: UIEvent.EventSubtype, with event: UIEvent?)// 远程控制事件
open func remoteControlReceived(with event: UIEvent?)// 按压事件
open func pressesBegan(_ presses: Set<UIPress>, with event: UIPressesEvent?)
open func pressesChanged(_ presses: Set<UIPress>, with event: UIPressesEvent?)
open func pressesEnded(_ presses: Set<UIPress>, with event: UIPressesEvent?)
open func pressesCancelled(_ presses: Set<UIPress>, with event: UIPressesEvent?)

主要分为三个模块:

下一个响应者对象一些关于第一响应者的方法事件回调方法(响应处理的地方)

这里有一个值得注意的地方,对象中的这个第一响应者,和之前Hit-Test得到的第一响应者并不同。通过测试发现,如果我们有A、B、C三个View,然后通过重写Hit-Test的方法控制B成为第一响应者,但是在页面加载出来之后调用C或者A的方法,却看不到任何变化。

但是目前看来这个方法的用途是控制系统键盘的弹出和隐藏。

首先,通过Hit-Test得到的第一响应者会优先触发它的时间回调方法,如果它并未重写该事件的方法,则会调用的实现,的实现就是找到下一个响应者对象,并且调用它的该事件方法,以此类推。

因此,如果一个响应者想要拦截这个事件,不让它继续往下传,只需要重写这个事件的回调方法,并且不调用super的这个方法就可以了。

在事件回调方法中包含NSSet对象和对象,NSSet对象中包含一个或者多个对象,下面我们简单介绍一下这两个重要的类,和

事件处理机制的应用 手势控制器

UIKit封装有类及它的基类来简化手势的监听处理。也是基于上述的事件回调方法来实现的,只是做了进一步的封装

响应传递事件方法包括__事件传递和事件响应

手势控制器的种类 使用Hit-Test来扩大点击范围

可以重写的::方法,来定义控件的响应范围,多用来增大按钮的点击范围或者增大的滑动范围。

处理兄弟控件的事件

可以重写的::方法,定义控件的响应范围为兄弟组件的显示范围,一次来通过在兄弟控件上的触控,响应自己的事件。

事件处理机制在系统控件中

目前一些系统组件有重写事件回调方法,并且做了一些特殊的事情。以下是两个例子

重写了和方法,用来实现点击的高亮效果。

重写了和方法,用来检测用户是不是真的有意图去滑动。如果用户在300ms之内并未有移动的事件,则会调用super方法,将事件处理权下发到子组件,但如果300ms内有移动,则就不会调用super方法,只是执行滑动效果。

参考资料

iOS事件机制

开发者官方文档

Touch 开发者官方文档

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了