点击事件的分发机制

点击事件的分发机制:一、事件的传递机制。二、响应链。

iOS中,当产生一个touch事件后,通过hit-Testing方法寻找hitTestView。

一、事件的传递机制

寻找过程如下:

通过点击屏幕,从最底层的UIWindow遍历subViews,默认顺序是按照subviews的逆顺序,找到hit-TestView就结束了。

判断是不是hit-TestView的方法如下:

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

1、当view的apla < 0.01或者view. userInteractionEnabled = NO或者view.hidden = YES,直接返回nil,不再进行后续判断。

2、通过hitPonitInside withevent方法判断触摸点是否在view上。

3、如果触摸点不在view上就返回nil,在的话就遍历view的subviews,重复上述动作。

4、遍历其subviews,如果view的subviews都返回空(都不是hit-TestView),返回自身(自身是hit-TestView)。

 

- ( UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{  
     //当view的apla < 0.01或者view. userInteractionEnabled = NO或者view.hidden = YES,直接返回nil,不再进行后续判断。
      if (self.alpha <= 0.01 || !self.userInteractionEnabled || self.hidden) {
           return nil;
      }
     //通过hitPonitInside withevent方法判断触摸点是否在view上。
 
      if (![self pointInside:point withEvent:event]) {
          return nil;
     }
    //遍历其subviews,重复上述步骤
 
      NSEnumerator *enumerator = [self.subviews reverseObjectEnumerator];
      for (UIView *subview in enumerator) {
               UIView *hitTestView = [subview hitTest:point withEvent:event];
               if (hitTestView)  {
                    return hitTestView;
                    }
         }
     //如果view的subviews都返回空(都不是hit-TestView),返回自身(自身是hit-TestView)
      return self;
}

二、响应链

找到hit-TestView后,事件就交给它处理了。这个时候hit-TestView就是firstResponder了,如果hit-TestView不能响应事件,那就把处理事件的权限交给它的nextResponder,直到找到响应者或者结束为止(传递到AppDelegate为止)。响应者的基类都是UIResponder。

UIView的nextResponder是直接管理它的UIViewController。 view.nextResponder = VC

UIViewController的nextResponder是管理其子view的view(UIWindow)VC.nextResponder = VC.view.superView

UIWindow的nextResponder是UIAppLication

UIAppLication的nextResponde是UIAppDelegate。

 

响应链上的某个对象处理事件之后可以选择让事件传递继续下去或者终止,如果需要让事件继续传递下去则需要在 touchesBegan 方法里面,调用父类对应的方法:

- ( void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
      // Responding to Touch Events
      [super touchesBegan:touches withEvent:event];
}


比如要在点击tabview的时候响应vc的touchesBegan方法,就要在scrollview的touchesBegan方法里调用父类的方法。

转载于:https://www.cnblogs.com/mahao/p/8608115.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值