iOS触摸事件传递与事件响应

2019-01-18  本文已影响23人  oldDevil

事件传递

传递

当手指触摸手机屏幕时会产生事件,那么事件是如何传递到我们点击View的呢,事实上事件首先会被放入事件循环中,等事件循环开始分发时先传给UIApplication,然后UIApplication传递给KeyWindow,KeyWindow传递给rootViewControllerView,随后rootViewController的View继续分发直到找到最合适的View
顺序 :事件循环 -> UIApplication -> KeyWindow -> View(rootViewController) -> 合适的view

事件传递顺序

如何寻找合适的View

规则:

1.判断view是否能够处理事件
2.判断点击point是否在view内
3.如果符合1、2步则遍历子view,从最后添加的子view开始向前遍历,重复1、2步
4.如果所有子view都不符合1、2条,则返回自己。如果有子View符合1、2步,则继续第3步操作

方法:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    return [super hitTest:point withEvent:event];
}

此方法可以修改事件传递的顺序,对应规则中的第一步,例如想当前view处理该事件,可以写return self;或者写一些其他的逻辑来改变事件传递的顺序,如果自己不想处理,则调用return [super hitTest:point withEvent:event];来按照系统的传递方式进行传递。

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    return YES;
}

此方法用来判断点击的点是否在该View内,通过重写该方法可以根据具体逻辑来更改寻找合适View规则的第二步,可以配合上面的方法来实现更复杂的逻辑。

用途:

1.点击超出父控件范围的view,正常不会响应,通过改变事件传递,来实现点击效果
2.同一层次结构上有重叠的view,通过点击View重合的部分,能够实现点击下面view的效果

事件响应链

事件传递到合适的View后,View可以选择处理该事件或者不处理该事件,如果不处理该事件,则该事件会往上一层View、Controller等传递,直到传递到UIApplication,如果还没有View、Controller等处理该事件,则该事件会被销毁。
顺序:合适的View -> View(Controller的view) -> Controller -> KeyWindow ->UIApplication


事件响应链

方法:

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {}
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {}
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {}

其中cancelled方法会在比如来电话时调用。

用途:

实现一个点击,多个View处理,方式为每个view重写touchesBegan等方法,实现完自己的处理后调用[super touchesBegan:touches withEvent:event];方法,使事件按照事件响应链继续向上传。

自定义事件的缺点:

1.必须定义子类
2.事件处理不好传递

上一篇下一篇

猜你喜欢

热点阅读