触摸事件的拦截

案例:三个叠在一起的图形,在重叠部分通过事件拦截来响应相应视图的手势。

 触摸事件的拦截

uiview不接受处理事件的三种情况:

  1. 不接收用户交互:userInterfactionEnable = no;
  2. 隐藏: hidden = yes;
  3. 透明:alpha  = 0~ 0.01

注意:通过storyBoard或xib创建的视图 , initwithFrame方法不会被执行,需要使用- (void)awakeFromNib;

实例化三种颜色的视图:

 1 - (void)awakeFromNib

 2 {

 3     

 4         RedView *view1 = [[RedView alloc]initWithFrame:CGRectMake(20, 210, 280, 40)];

 5         [self addSubview:view1];

 6         self.redView = view1;

 7         

 8         BlueView *view2 = [[BlueView alloc]initWithFrame:CGRectMake(60, 130, 200, 200)];

 9         [self addSubview:view2];

10         [view2 setAlpha:0.5];

11         self.blueView = view2;

12         

13         GreenView *view3 = [[GreenView alloc]initWithFrame:CGRectMake(80, 150, 160, 160)];

14         [self addSubview:view3];

15         [view3 setAlpha:0.5];

16         self.greenView = view3;

17 

18 }

 

通过以下两个方法来进行手势拦截:

  - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
  - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;

重写hittext方法,拦截用户触摸视图的顺序
hitTest方法的都用是由window来负责触发的。
如果希望用户按下屏幕 , 就立刻做出响应 , 使用touchesBegin
如果希望用户离开屏幕 , 就立刻做出响应 , 使用touchesEnd
通常情况下使用touchesBegin,以防止用户认为点击了没有反应。

把hitTest的点转换为 redView的点,使用convertPoint: toView;

 CGPoint redP = [self convertPoint:point toView:self.redView];

判断一个点是否在视图的内部:

if ([self.greenView pointInside:greenP withEvent:event]) {
return self.greenView;
}

hitTest拦截时间的代码:

 1 -(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

 2 {

 3     //1.判断当前视图是否能接受用户响应

 4     /*self.UserInteractionEnabled=YES

 5       self.alpha > 0.01;

 6       self.hidden = no;

 7      */

 8     //2.遍历其中的所有的子视图,能否对用户触摸做出相应的响应

 9     //3.把event交给上级视图活上级视图控制器处理

10     //4.return nil;如果返回nil,说明当前视图及其子视图均不对用户触摸做出反应。

11     /*

12      参数说明:

13         point:参数是用户触摸位置相对于当前视图坐标系的点;

14      注视:以下两个是联动使用的,以递归的方式判断具体响应用户事件的子视图

15             - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;

16             - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;

17         这两个方法仅在拦截触摸事件时使用,他会打断响应者链条,平时不要调用。

18      提醒:如果没有万不得已的情况,最好不要自己重写hitTest方法;

19      */

20     CGPoint redP = [self convertPoint:point toView:self.redView];

21     //转换绿色视图的点

22     CGPoint greenP = [self convertPoint:point toView:self.greenView];

23     //pointInside  使用指定视图中的坐标点来判断是否在视图内部,最好不要在日常开发中都用。

24     if ([self.greenView pointInside:greenP withEvent:event]) {

25         return self.greenView;

26     }

27     NSLog(@"%@",NSStringFromCGPoint(redP));

28     if ([self.redView pointInside:redP withEvent:event]) {

30         return self.redView;

31     }

33     return [super hitTest:point withEvent:event];

34 }

代码在:https://github.com/zhangjinling/IOSProgects/tree/master/%E6%89%8B%E5%8A%BF/03.%E8%A7%A6%E6%91%B8%E4%BA%8B%E4%BB%B6%E6%8B%A6%E6%88%AA

你可能感兴趣的:(事件)