iOS中只有继承UIResponder的对象才能够接收并处理事件,UIResponder是所有响应对象的基类,在UIResponder中定义了处理上述各种事件的接口。UIApplication,UIWindow,UIViewController,UIView都是直接或者间接继承自UIResponder,所以他们的实例都可以构成响应链的响应者对象。
响应链:
当点击(Touch)发生的时候,系统会将其打包成一个UIEvent,并放入到当前活动的UIApplication事件队列中,单例的UIApplication会将事件发送给单例的UIWindow来处理;UIWindow首先会用hit-test:withEvent:寻找此次Touch操作所在的视图
runloop响应图- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event{
// 1.如果控件不允许与用用户交互,那么返回nil
if(self.userInteractionEnabled ==NO||self.alpha <=0.01||self.hidden ==YES){
return nil;
}
// 2. 如果点击的点在不在当前控件中,返回nil
if(![self pointInside:point withEvent:event]){
return nil;
}
// 3.从后往前遍历每一个子控件
for(inti = (int)self.subviews.count -1; i >=0;i--){
// 3.1获取一个子控件
UIView*childView =self.subviews[i];
// 3.2当前触摸点的坐标转换为相对于子控件触摸点的坐标
CGPoint childP = [self convertPoint:point toView:childView];
// 3.3判断是否在在子控件中找到了更合适的子控件(递归循环)
UIView*fitView = [childView hitTest:childP withEvent:event];
// 3.4如果找到了就返回
if(fitView) {
return fitView; }
}
// 4.没找到,表示没有比自己更合适的view,返回自己
return self;
}
网友评论