Button相应起首从触摸屏幕开始
在这之前,必要相识坐标转换及缘故原由
步调员的逻辑每每如图所示
也就是UI逻辑中,使用的坐标点每每是相对于父结构的,而结构会嵌套多层
屏幕上的触点,判定落点归属于哪个UI控件的话,就必要让全部UI控件的坐标点转换为相对于 window的
如许转换后的坐标就变为
直观是如许的逻辑,但真实的检测过程实际是 按照ui嵌套层级关系递归举行的,也就是从window开始,一级一级子视图倒序遍历举行
如许在每递归到某一层view时,就必要对此view子视图举行检测,这个时间就必要把当前view上的触点坐标转换为 子视图view上的坐标
说白了,在检测阶段,每次递归检测时,转换坐标 就是遍历子view时,point从相对于当前view 改变为 相对于 子view,也就是改变了参考基点
简朴梳理流程
- 触摸屏幕
- IOKit.framework捕捉,封装IOHIDEvent对象
- 通过IPC(历程间通讯)转发给SpringBoard历程
- 通过IPC将变乱转发给当前生动的历程 AppDelegate
- app主线程runloop通过port signal(来自于SpringBoard历程)检测到source1, 线程由休眠状态被激活,runloop继承轮询
- runloop检测到source0(InputSource), 封装UIEvent,参加到 当前application的event队列
- 变乱出队列, sendEvent发送给window
- window 开始查询相应者
- rootViewController-view 按照子view 倒序递归查询
- pointInside 判定触点是否落在当前view 的bounds内
- hitTest, 假如触点落在当前view的bounds内, 转换触点坐标为相对于屏幕的坐标点,递归倒序遍历子view hitTest检测
- 之以是当前view子view数组遍历接纳倒序,末了的view为嵌套层的最上层,服从高
- 检测大概出现3种结果
- 目的相应者 ui交互是禁止的 而且不是完全透明 不是隐蔽的,结果就是没有相应者了(nil)
- view的某个子视图 为目的相应者
- 当前view为 目的相应者
- window sendTouchesForEvent 发送给以上查询到的相应者, 假如相应者nil,就没有后续处置惩罚了
- touchBegan/touchMoved/touchEnded/touchCancelled 捕捉处置惩罚
- 回调相应者预先设置的 handleCallback,也就是 selector, 并转达相应者自身作为 参数
- 根据touch 几种逻辑判定,选择符合的callback
- 比如按下按钮 配景颜色变革
- 脱离按钮 颜色规复等等 各种touch的变乱表明类型, 差别类型实行对应差别的callback
- 假如相应者未处置惩罚 touch, 就会沿着相应查找链条反向转达给父视图, 直到 application, 也就是假如目的相应者未相应,会沿着转达链条回溯回到 application, application默认不做处置惩罚
- 处置惩罚竣事,app的runloop进入休眠,期待下次叫醒
apple-touch封装
touchBegan/touchMoved/touchEnded/touchCancelled 是底层的方式
apple提供了高级封装 UIGestureRecognizer 和 UIControl
UIGestureRecognizer 包罗8种手势
- UITapGestureRecognizer 轻点
- UIPinchGestureRecognizer 捏和
- UIRotationGestureRecognizer 旋转
- UISwipeGestureRecognizer 滑动
- UIPanGestureRecognizer 拖拽
- UIScreenEdgePanGestureRecognizer 屏幕边沿拖拽
- UILongPressGestureRecognizer 长按
- UIHoverGestureRecognizer 悬停(macOS & iPadOS)
window sendTouchesForEvent 后续流程修正
上面的流程是基于底层方式形貌,针对于apple封装的 UIGestureRecognizer,做出调解
window 查询到具体的 相应者之后
- window sendTouchesForEvent 发送给以上查询到的相应者; 同时也会发送给 相应者视图绑定的 gestureRecognizers
- 相应者视图 某个 gestureRecognizer 辨认匹配乐成,就会回调相应者 touchCancelled方法,相应者不再吸收 touch变乱
- 由于 手势互斥,其他的 gestureRecoginzer 也会回调 touchCancelled方法,且不再吸收 touch变乱
- 辨认乐成的gesture 设置的target - action 实行
- 否则,继承 touchBegan/touchMoved/touchEnded 及后续处置惩罚
- 处置惩罚竣事,app的runloop进入休眠,期待下次叫醒
另有一些额外设定, 比如:
- 辨认乐成之后,是否取消其他相应 cancelsTouchesInView [true or false]
- delaysTouchesBegan 是否在手势辨认失败之后,才将touchBegin变乱转达给 相应者
- delaysTouchesEnded 是否在手势辨认失败之后,才将touchEnded变乱转达给 相应者
流程进一步细化
UIControl 是UIView子类
保持前面修正的流程
- 假如相应者 是 UIButton、UISwitch、UISlider 这些体系控件,也就是 UIControl体系子类, target - action实行, 相应者不再吸收 touchBegan等变乱
|