当用户用一根手指触摸屏幕时,会创建一个与手指相关的UITouch对象,一根手指对应一个UITouch对象
如果两根手指同时触摸一个view,那么view会调用一次touchesBegan:withEvent方法,touches参数中装着2个UITouch对象
如果两个手指一前一后触摸同一个view那么view会分别调用两次touchesBegan:withEvent方法,并且每次调用时的touches参数中只包含一个touch对象
UITouch的作用:
1.保存着手指的相关信息,比如触摸的位置,事件,阶段
2.当手指移动时,系统会更新同一个UITouch对象,使之能够一直保存该手指在的触摸位置
3.当手指离开屏幕时,系统会销毁相应的UITouch事件
UITouch的属性:
//触摸发生时所处的窗口
@property(nonatomic, readonly, retain)UIWindow *window;
//触摸发生时所处的view
@property(nonatomic, readonly, retain)UIView *view;
//短时间内点按屏幕次数,单击,双击或者多击
@property(nonatomic, readonly)NSUInteger tapCount;
//记录了触摸事件产生或者变化时的时间,单位时秒
@property(nonatomic, readonly)NSTimeInterval timestamp;
//当前触摸事件所处的状态
@property(nonatomic, readonly)UITouchPhase phase;
UITouch的方法:
//返回值:触摸在view上的位置,是针对view的坐标系的(以view的左上角为原点)若调用时view传参是nil则返回的触摸点在UIWindow的位置
-(CGPoint):locationInView:(UIView *)view;
//记录前一个触摸点的位置
-(CGPoint):preViousLocationInView:(UIView *)view;
UIView不能接收触摸事件的三种情况
1.不允许交互: userInteractionEnabled = No
2.隐藏: 如果父控件隐藏的话,那么子控件也会隐藏,隐藏的控件不能接收事件
3.透明度:如果设置一个控件的透明度小于0.01,会直接影响子控件的透明度.alpha:0~0.01为透明.
寻找最合适的view底层剖析,两个重要方法:
hitTest: withEvent:
pointInSide
1. hitTest: withEvent: 方法
何时调用:
只要事件传递给一个控件,这个控件就会调用自己的hitTest: withEvent: 方法
作用:
寻找并返回最合适的view(能够响应事件的最合适的view)不管这个控件能不能处理事件,也不管触摸点在不在这个控件上,事件都会先传递给这个控件,随后再调用hitTest: withEvent:方法
拦截事件的处理:
正因为hitTest: withEvent: 方法可以返回最合适的view,所以可以通过重写hitTest: withEvent: 方法,返回指定的view作为最合适的view.
不管点击哪里最合适的view都是hitTest: withEvent: 方法中返回的那个view.
通过重写hitTest: withEvent: 就可以拦截事件的传递过程,想让谁处理事件谁就可以处理事件.
事件传递给谁,就会调用谁的hitTest: withEvent: 方法.
如果hitTest: withEvent: 方法返回nil,那么调用该方法的控件本身和其子控件都不是最合适的view,也就是在自己身上没有找到更合适的view.那么最合适的view就是该控件的父控件.
特殊情况:
谁都不能处理的事件,window也不能处理
重写window的hitTest: withEvnet 方法返回nil
只能window处理
控制器的view的hitTest: withEvent: 方法返回nil或者window的hitTest: withEvent: 方法return self;
2. pointInSide: withEvent: 方法
pointInSide: withEvent: 方法判断点不在当前view上(方法调用者的坐标系上)如果返回YES,代表点在方法调用者的坐标系上,否则表示点不在方法调用者的坐标系上,那么方法调用者也不能处理事件.
网友评论