源码下载
iOS事件分类
1.Touch Events(触摸事件)
2.Motion Events(运动事件)
3.Remote Events (远程事件)
4.Press Events(按压事件)
事件处理周期:
1.事件产生和传递
2.找到合适的view处理
3.处理事件或者舍弃
这里主要是说触摸事件。
响应者对象:可以处理事件的对象,即UIResponder的子类对象。
事件响应链:通过UIResponder的属性串连在一起的一条虚拟的链,用来对App事件进行处理。
- (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; //触摸被中断,例如触摸时电话呼入
如果iOS要对事件进行响应,则这个对象必须继承了UIResponder的对象。就算是继承了UIResponder也有情况不能进行事件响应。
不能响应iOS事件的对象:
1.不是UIResponder的子类。
2.控件的userInteractionEnabled属性为NO。
3.控件被隐藏了(父控件被隐藏,所有的子控件也被隐藏)。
4.透明对低于0.01。
响应事件在响应者链中的传递过程。
1 事件产生之后,会被加入到UIApplication管理的时间队列里,接下来就自UIApplication向下传递,首先传给主window,window传给根view,然后按照view的层级一层一层的传递一直到找到最合适的view来处理事件。
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;//方法作用是返回最合适处理事件的对象
pointInside:withEvent:方法作用是判断点是否在视图内,是则返回YES,否则返回NO
2 根据响应者的判断,如果当前窗口不是合适的响应者,则会把消息传递给响应链中的下一个响应者。
下一个响应者的判断原则
UIView
如果当前的view为控制器的根view,那么控制器就是下一个响应者。如果当前view不是控制器的view,则这个view的父控件就是下一个响应者。
UIViewController
如果viewcontroller的view是window的根view,那么下一个响应者就是window,如果viewcontroller是模态出来的,下一个响应者就是模态出这个viewcontroller的viewController,如果viewcontroller的view是被add到另外一个Controller的根view上,那么下一个响应者就是viewcontroller的根view。
UIWindow
UIWindow的下一个响应者是UIApplication
UIApplication
通常UIApplication是响应者链的最顶端(如果app delegate也是UIRespoonder的子类对象,那么事件还会传给app delegate)
3.如果再视图层次结构的最顶层还是不能处理事件或者消息就把事件传递给window对象进行处理。
4.如果window对象也不处理,就把对象交给UIApplication对象。
5.如果UIApplication对象也不处理就丢弃。
响应者链的代码
UIResponder * next = [self nextResponder];
NSMutableString * prefix = @"".mutableCopy;
while (next != nil) {
NSLog(@"%@%@", prefix, [next class]);
[prefix appendString: @"--"];
next = [next nextResponder];
}
源码
MyTouchView.h
//
// MyTouchView.h
// ShiJianDemo
//
// Created by liuyinghui on 2018/3/5.
// Copyright © 2018年 liuyinghui. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface MyTouchView : UIView
@end
MyTouchView.m
//
// MyTouchView.m
// ShiJianDemo
//
// Created by liuyinghui on 2018/3/5.
// Copyright © 2018年 liuyinghui. All rights reserved.
//
#import "MyTouchView.h"
@implementation MyTouchView
- (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event{
NSLog(@"%@",self);
return [super hitTest:point withEvent:event];
} // recursively calls -pointInside:withEvent:. point is in the receiver's coordinate system
@end