iOS触摸事件解析

首先介绍UITouch: 

UITouch简介:

           当用户用一根手指触摸屏幕时,会创建一个与手指相关联的UITouch对象,一根手指对应一个UITouch对象(UIView默认是只能有一个手指触摸 要想能接收多个手指的触摸 需要设置Multiple Touch.)

           当手指移动时,系统会更新同一个UITouch对象,使之能够一直保存该手指的触摸位置。

           当手指离开屏幕时,系统会销毁相应的UITouch对象

UITouch的两个重要方法 : (通过这两个方法获取当前触摸点和之前触摸点的坐标)

         - (CGPoint)locationInView:(UIView*)view; 获取点的当前位置

返回值表示触摸在view上的位置,这里返回的位置是针对view的坐标系的(以view的左上角为原点(0, 0)

调用时传入的view参数为nil的话,返回的是触摸点在UIWindow的位置

- (CGPoint)previousLocationInView:(UIView *)view; 获取点的上一个位置

该方法记录了前一个触摸点的位置

触摸事件的产生和传递:

1.发生触摸事件后,系统会将该事件加入到一个由UIApplication管理的事件队列中

2.UIApplication会从事件队列中取出最前面的事件,并将事件分发下去以便处理,通常,先发送事件给应用程序的主窗口(keyWindow

3.主窗口会在视图层次结构中找到一个最合适的视图来处理触摸事件,但是这仅仅是整个事件处理过程的第一步

4.找到合适的视图控件后,就会调用视图控件的touches方法来作具体的事件处理

touchesBegan…

touchesMoved…

touchedEnded…

 

如何找到一个最合适的视图(笼统):    (如果父控件不能接收触摸事件,那么子控件就不可能接收到触摸事件.)

1> 自己是否能接收触摸事件?若为否,直接返回nil.(直接返回nil表示包括该控件自己及其子控件都不处理这个触摸事件.)

注:UIView不接收触摸事件的三种情况: 1.不接收用户交互userInteractionEnabled = NO    2. 隐藏 hidden= YES     3. 透明 alpha = 0.0 ~0.01

2> 触摸点是否在自己身上?若为否,直接返回nil.

3> 前面两个条件若都满足, 从后往前遍历子控件,重复前面的两个步骤.

4> 如果没有符合条件的子控件,那么就返回self,表示自己最适合处理.

如何找到一个最合适的视图(详细):

先介绍两个在触摸过程中会调用的方法:

1.   - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;  上面笼统的四步就是通过调用这个方法来执行的.

2.   - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event; 帮助第一个方法来判断触摸点是否在自己身上. 注意: 其中的point必须是基于本控件的坐标系!!!!

现在正式开始介绍(UIView *)hitTest:(CGPoint)pointwithEvent:(UIEvent *)event方法的具体实现:

       1.判断自己是否能被触摸 :

if (self.userInteractionEnabled== NO || self.hidden == YES || self.alpha <= 0.01) return nil;

  2.判断点在不在当前控件上面:

                if (![selfpointInside:point withEvent:event]) return nil;

  3. 从后往前遍历子控件,遍历的过程中调用它们的hitTest: withEvent: 的方法.   注意: 传入point的之前,需要将point转换为基于子控件的坐标系(注意:不是子控件所在的坐标系): CGPoint childPoint = [self convertPoint:point toView:childView];

              一旦有一个子控件返回的UIView不为空 则返回它返回的view ,因为它就是我们要找得最合适的视图!

      4.在第三步中没有找到比自己更合适的子view,那么返回自己即可, 自己即是最合适的视图

介绍完了机制 来几个题目:

1.   如何屏蔽一个控件的所有子控件的触摸事件?

重写该控件的 hitTest 方法 ,然后判断一下是否能被触摸,且点是否在自己身上,如果都没有问题 不遍历子控件 直接返回自己.(表示本控件就是最合适的视图)

2.   如果一个控件覆盖在button的上面, 如何做到 当点击在这个button上面的时候 能够让button处理到触摸事件?

重写该控件的hitTest 方法, 首先判断点是否在button上面(判断之前,记得把point转化为基于button的坐标系). 若在,那么直接返回这个button(表示button就是最合适的视图)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值