当一个控件不能接收事件时通常有如下几种状况
1.不接收用户交互userInteractionEnabled = NO
2.当一个控件隐藏时Hidden = YES
3.当一个控件的Alpha = 0.0~0.01
的时候ios
####注意:UIImageView
以及它的子控件默认是不能接收触摸事件的ide
用户点击屏幕产生的一个触摸事件,通过一系列的传递过程后,会找到一个最适合的视图来处理事件.找到最合适的视图控件后,就会调用控件的touches
方法来做具体的事件处理.touches
的默认作法是将事件顺着响应者链条向上传递,将事件交给上一个响应者处理code
1.先判断本身是否能接收触摸事件
2.再判断触摸的当前点在不在本身身上
3.若是在本身身上,它会从后往前遍历子控件,遍历出每个控件后,重启前两步
4.若是没有符合条件的子控件,那么自身就是最合适的View对象
//做用:寻找最适合的View //何时调用:当事件传递给当前View时就会调用这个方法 -(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{ UIView *fitView = [super hitTest:point withEvent:event]; NSLog(@"%@",fitView); return fitView; } //做用:判断触摸点在不在当前的View上. //何时调用:在hitTest方法当中会自动调用这个方法. //注意:point必须得要跟当前View同一个坐标系. -(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{ return YES; }
那么hitTest: withEvent:
方法底层是如何实现的呢?继承
// 判断本身可否接收事件 if(self.userInteractionEnabled == NO || self.hidden == YES || self.alpha <= 0.01){ return nil; } // 触摸点在不在本身身上 if ([self pointInside:point withEvent:event] == NO) { return nil; } // 从后往前遍历本身的子控件(重复前面的两个步骤) int count = (int)self.subviews.count; for (int i = count -1; i >= 0; i--) { UIView *childV = self.subviews[i]; // point必须得要跟childV相同的坐标系. // 把point转换childV坐标系上面的点 CGPoint childP = [self convertPoint:point toView:childV]; UIView *fitView = [childV hitTest:childP withEvent:event]; if (fitView) { return fitView; } } // 若是没有符合条件的子控件,那么就本身最适合处理 return self;