响应者链

参考:http://www.javashuo.com/article/p-rigmnzyj-hm.html
先执行事件链,找到合适的view,在执行响应链。

一、事件链

UIApplication -> window -> view -> view ……..->view
a. 当iOS程序中发生触摸事件后,系统会将事件加入到UIApplication管理的一个任务队列中
b. UIAplication 将处于任务队列最前端的事件向下分发,即UIWindow
c. UIWindow 将事件向下分发,即UIView
d. UIView首先看自己是否能处理事件(hidden = NO, userInteractionEnabled = YES, alpha >= 0.01),触摸点是否在自己身上。如果能,那么继续寻找子视图
e. 遍历子控件(从后往前遍历),重复上面的步骤。
f. 如果没有找到,那么自己就是事件处理着,如果自己不能处理,那就不做任何事

  • 事件链的过程其实就是 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
    函数的执行过程。


    image.png
image.png

二、响应链

响应链是从最合适的view开始传递,处理事件传递给下一个响应者,响应链的传递是个事件链传递相反的。如果所有响应者都不处理事件,则事件被丢弃。通常获取级响应者是通过nextResponder方法的。

  • 通常找到对应的view之后然后查找此view是否能处理此事件。
    其实也就是看view能否依次响应下面的几个方法(并不一定是全部)来构成一个消息。
  • (void)touchesBegan:(NSSet *)touches withEvent:(nullable UIEvent *)event;
  • (void)touchesMoved:(NSSet *)touches withEvent:(nullable UIEvent *)event;
  • (void)touchesEnded:(NSSet *)touches withEvent:(nullable UIEvent *)event;
  • (void)touchesCancelled:(NSSet *)touches withEvent:(nullable UIEvent *)event;

例如:

1.按钮上添加手势情况1

    UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem];
    [btn setTitle:@"按钮" forState:UIControlStateNormal];
    btn.frame = CGRectMake(40, 200, 50, 30);
    btn.backgroundColor = [UIColor greenColor];
    [self.view addSubview:btn];

    [btn addTarget:self action:@selector(btnAction) forControlEvents:UIControlEventTouchUpInside];

    UITapGestureRecognizer *tap1 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction1)];
    [btn addGestureRecognizer:tap1];


- (void)btnAction {
    NSLog(@"按钮点击的");
}

- (void)tapAction1 {
    NSLog(@"手势1");
}

点击按钮后执行的结果是:

手势1
为什么呢?

由于当我们添加了UITapGestureRecognizer手势之后,当nextResponder为当前的viewcontroller时,它走touches的几个方法时先构成了tap手势的消息发送,因此打印的结果是手势1

2.按钮上添加手势情况2

    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction)];
    [btn addGestureRecognizer: pan];

- (void)panAction {
    NSLog(@"手势");
}

给按钮上添加的是平移手势

当我们点击按钮时结果为

按钮点击的

当我们平移按钮时结果为

手势

3.按钮上添加手势情况3

    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction)];
    [btn addGestureRecognizer: pan];

    UITapGestureRecognizer *tap1 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction1)];
    [btn addGestureRecognizer:tap1];
    
    
    [btn addTarget:self action:@selector(btnAction1) forControlEvents:UIControlEventTouchDragInside];

- (void)tapAction {
    NSLog(@"手势");
}
- (void)tapAction1 {
    NSLog(@"手势1");
}
- (void)btnAction1 {
    NSLog(@"按钮点击的1");
}

当按钮的controlEvents为UIControlEventTouchDragInside时
,同时添加了平移和轻拍手势

当我们点击按钮时执行的是 轻拍手势

手势1

当我们平移按钮时,平移的手势和按钮的响应都执行了

按钮点击的1

手势

你可能感兴趣的:(响应者链)