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];
}
}
网友评论