美文网首页
(hitTest:withEvent:)事件的产生和传递

(hitTest:withEvent:)事件的产生和传递

作者: Areyouhere | 来源:发表于2017-01-12 10:22 被阅读0次

1.UIResponder内容提供了以下方法来处理事件
∙触摸事件

-(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent *)event

-(void)touchesEnded:(NSSet*)touches withEvent:(UIEvent *)event

-(void)touchesMoved:(NSSet*)touches withEvent:(UIEvent *)event

-(void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent *)event

∙加速事件

-(void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event

-(void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event

-(void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event

∙远程控制事件

-(void)remoteControlReceivedWithEvent:(UIEvent *)event

2.触摸事件的事件产生和 传递

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

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

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

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

∙ 触摸事件的传递是从父控件传递到子控件

点击了绿色的view: UIApplication-UIWindow-白色-绿色

点击了黄色的view: UIApplication-UIWindow-白色-橙色-蓝色-黄色

∙如果父控件不能接收触摸事件,那么子控件就不可能接收到触摸事件

∙ 如何找到最合适的控件来处理事件?

1)自己是否能接收触摸事件?(判断,userInteractionEnabled=yes;hidden=no;alpha(>0.01))

2)触摸点是否在自己身上

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

3)从后往前遍历子控件,重复前面的两个步骤

-(UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event(返回最合适的控件)
4)如果没有符合条件的子控件,那么自己就是最合适的控件处理

∙自己实现 hitTest:withEvent:

-(UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
      //1.判断当前控件能否接收事件
      if (self.userInteractionEnabled==NO || self.hidden==YES||self.alpha<=0.01)return nil;
     //2.判断点在不在当前控件
     if ([self pointInside:point withEvent:event]==NO)return nil;

    //3.从后往前遍历自己的子控件

      NSInteger count=self.subviews.count;
      for (NSInteger i=count-1; i>=0; i--)
      {
       UIView*childView=self.subviews[i];

      //把当前控件上的坐标系统转换成子控件上的坐标系
 
       CGPoint childPoint=[self convertPoint:point toView:childView];

       //子控件重复上面的步骤

          UIView*fitView=[childView hitTest:childPoint withEvent:event];

       if (fitView)return fitView;//寻找到最合适的view
        }
    return self;//循环结束 如果子控件没有最合适的 那么自己就是最合适的
}

∙ 一些超出自己控件实现点击方法 或在视图下面的方法

 -(UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
//1.转换成要实现点击方法的视图 坐标系
CGPoint proPoint=[self convertPoint:point toView:self.profileButton];
if ([self.profileButton pointInside:proPoint withEvent:event])
{
          return self.profileButton;
}
else 
{
     return [super hitTest:point withEvent:event];
}
}

相关文章

网友评论

      本文标题:(hitTest:withEvent:)事件的产生和传递

      本文链接:https://www.haomeiwen.com/subject/ftsdbttx.html