触摸事件拦截
#import "RootView.h"
#import "RedView.h"
#import "BlueView.h"
#import "GreenView.h"

@interface RootView()

@property (weak, nonatomic) RedView *redView;
@property (weak, nonatomic) BlueView *blueView;
@property (weak, nonatomic) GreenView *greenView;

@end

@implementation RootView

#pragma mark - 通过Storyboard或者xib创建的视图,initWithFrame方法不会被调用
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        NSLog(@"initWithFrame");
    }
    return self;
}

- (void)awakeFromNib
{
    RedView *view1 = [[RedView alloc]initWithFrame:CGRectMake(20, 210, 280, 40)];
    [self addSubview:view1];
    self.redView = view1;
    
    BlueView *view2 = [[BlueView alloc]initWithFrame:CGRectMake(60, 130, 200, 200)];
    [self addSubview:view2];
    [view2 setAlpha:0.5];
    self.blueView = view2;
    
    GreenView *view3 = [[GreenView alloc]initWithFrame:CGRectMake(80, 150, 160, 160)];
    [view3 setAlpha:0.5];
    [self addSubview:view3];
    self.greenView = view3;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    NSLog(@"点根视图了");
}

/**
 重写hitTest方法,拦截用户触摸视图的顺序
 
 hitTest方法的调用是由window来负责触发的
 */
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    /**
     1. 判断当前视图能否接受用户响应
     
     self.userInteractionEnabled = YES;
     self.alpha > 0.01;
     self.hidden == NO;
    
     2. 遍历其中的所有子视图,是否对用户触摸做出相应
     
     3. 如果返回nil,说明当前视图及子视图均不对用户触摸做出响应
        此时,把event交给上级视图或者视图控制器处理
     
     参数说明:
     point: 参数是用户触摸位置相对当前视图坐标系的点
     
     注释:
     以下两个方法是联动使用的,以递归的方式判断具体响应用户事件的子视图
     以下两个方法仅在拦截触摸事件时,才可以使用,平时不要调用
     - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
     - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;
     
     提醒:
     
        如果没有万不得已的情况,最好不要自己重写hitTest方法!!!
     */
    NSLog(@"%@", NSStringFromCGPoint(point));
    
    // 转换绿色视图的点
    CGPoint greenPoint = [self convertPoint:point toView:self.greenView];
    
    // 来使用指定视图中的坐标点判断该点是否在对应视图内部
    // 提醒,此方法,日常开发中,不要去调用
    if ([self.greenView pointInside:greenPoint withEvent:event]) {
        return self.greenView;
    }
    
    // 需要转换成红色视图坐标系对应的点
    CGPoint redPoint = [self convertPoint:point toView:self.redView];
    NSLog(@"红色视图坐标系中的点 %@", NSStringFromCGPoint(redPoint));
    
    if ([self.redView pointInside:redPoint withEvent:event]) {
        return self.redView;
    }
    
    return [super hitTest:point withEvent:event];
}

@end
View Code

 

posted on 2015-07-16 21:23  pTrack  阅读(103)  评论(0)    收藏  举报