iOS事件
运动事件,远程控制事件、触摸事件
image.png
触摸事件
事件传递的顺序
EOCLightGrayView *grayView = [[EOCLightGrayView alloc] initWithFrame:CGRectMake(50.f, 100.f, 260.f, 200.f)];
EOCRedView *redView = [[EOCRedView alloc] initWithFrame:CGRectMake(0.f, 0.f, 120.f, 100.f)];
EOCBlueView *blueView = [[EOCBlueView alloc] initWithFrame:CGRectMake(140.f, 100.f, 100.f, 100.f)];
EOCYellowView *yellowView = [[EOCYellowView alloc] initWithFrame:CGRectMake(50.f, 360.f, 200.f, 200.f)];
[self.view addSubview:grayView];
[grayView addSubview:redView];
[grayView addSubview:blueView];
[self.view addSubview:yellowView];
image.png
当点击红色的时候 打印为
2020-05-26 20:12:27.319652+0800 事件层次分析 [67838:232210] yellowColorView pointInside
2020-05-26 20:12:27.319911+0800 事件层次分析 [67838:232210] ligthGrayColorView pointInside
2020-05-26 20:12:27.320128+0800 事件层次分析 [67838:232210] blueColorView pointInside
2020-05-26 20:12:27.320301+0800 事件层次分析 [67838:232210] redColorView pointInside
事件传递的方法
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
-
hitTest方法会判断pointInside是不是在view里面 如果是的话 就进行遍历,同时返回真正事件相应的对象
image.png
-
当不在view里面的话 就返回nil
image.png
-
当点击的是自己的时候 就返回自己
image.png
代码实现
案列
- 按钮过小 扩大点击范围
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
NSLog(@"%s",__func__);
//在我想要的区域,pointInside返回YES
CGRect rect = self.bounds;
if (rect.size.width < 50.f) {
rect.origin.x -= (50.f - rect.size.width)/2;
}
if (rect.size.height < 50.f) {
rect.origin.y -= (50.f - rect.size.width)/2;
}
rect.size.width = 50.f;
rect.size.height = 50.f;
if (CGRectContainsPoint(rect, point)) {
return YES;
}
return [super pointInside:point withEvent:event];
}
- 超出范围
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
NSArray *subviews = [[self.subviews reverseObjectEnumerator] allObjects];
UIView *tmpView = nil;
for (UIView *view in subviews) {
CGPoint converedPoint = [self convertPoint:point toView:view];
if ([view pointInside:converedPoint withEvent:event]) {
tmpView = view;
break;
}
}
if (tmpView) {
return tmpView;
}else if ([self pointInside:point withEvent:event]){
return self;
}else{
return nil;
}
}
响应链
image.png
image.png
点击红色位置之后 响应链是从底部一层层的往上传递 如果上层有view 就传递给view 如果没有view 就传给ViewController
手势事件
-
手势事件和hitTest pointInSide的关系
1.当点击在手势的视图上时 响应了手势的点击事件
image.png
2.当hitTest返回nil的时候 没有响应手势的点击事件
image.png
手势的响应的前提也是要先找到这个对象
touch事件是View本身就有的事件 手势事件是叠加在View上的事件
-
当通过hitTest和pointInside找到了View 然后如果View或者他的superView有手势事件 都会响应
image.png
当在grayView上添加手势 点击红色区域或者蓝色区域的时候 都会响应手势
image.png
-
手势和View的touch事件的关系
当手势响应之后 会取消掉View的touch事件
image.png
可以通过
tapGesture.delaysTouchesBegan = NO; // 是否延迟View的touch事件的识别,如果为YES,阻止touch方法的识别 如果延迟了 手势也识别了的话 就放弃touch事件
tapGesture.cancelsTouchesInView = NO;// 识别手势之后 是否取消View的touch事件
来改变touch事件是否执行
button事件
- button事件和hitTest pointInSide的关系
button的响应的前提也是要先找到这个对象
- 通过button里面的四个touch的方法来判断是哪种button事件
多手势的共存和互斥
- 多手势的共存
//手势支不支持touch
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
return YES;
}
//手势已经识别,通过这个方法的返回值,看是否响应
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
return YES;
}
//两个手势是否共存(一起响应),A手势和B手势,只要这两个手势有一个手势的这个代理方法返回的YES,那么就是共存
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
当这个方法返回YES的时候 就是多个手势都响应 只要有一个手势的类里面实现了这个方法 并且返回YES 那么他这个手势就跟其他手势是共存的 必须2个手势同时设置为NO 才不共存
- 多手势的互斥
//互斥用的:gestureRecognizer它要响应,必须得满足otherGestureRecognizer响应失败,才可以,otherGestureRecognizer的优先级最高
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
}
//互斥用的:otherGestureRecognizer它要响应,需要gestureRecognizer响应失败,才可以,gestureRecognizer的优先级最高
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
[手势2 requireGestureRecognizerToFail:手势1];
设置手势2必须在手势1响应失败的情况下 才能响应 以实现手势的互斥
tableview的cell的点击事件走的是touch事件













网友评论