iOS 响应链相关小结

2018-12-13  本文已影响0人  sooon77

传递链

UIApplication -> UIWindow -> UIView -> initial view,以上就是事件的传递,也就是寻找最合适的view的过程。

响应链

传递链反过来

寻找合适的View

两个重要的方法:

hitTest:withEvent:方法

pointInside方法

不响应的前置条件 不会调用hitTest

  1. 不允许交互:userInteractionEnabled = NO

  2. 隐藏:如果把父控件隐藏,那么子控件也会隐藏,隐藏的控件不能接受事件

  3. 透明度:如果设置一个控件的透明度<0.01,会直接影响子控件的透明度。alpha:0.0~0.01为透明。

  4. 子视图超出父视图的情况

Note:默认UIImageView不能接受触摸事件,因为不允许交互,即userInteractionEnabled = NO,所以如果希望UIImageView可以交互,需要userInteractionEnabled = YES。

应用


- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {

// toView 重在后参数,把point转换成toView参数代表的View之上的坐标

// fromView 重在调用者 把point转换成调用View之上的坐标

CGPoint point1= [self convertPoint:point toView:self];

CGPoint point2= [self.superview convertPoint:point fromView:self];

for (UIView *view in self.subviews) {

// 把当前point转换为子View所在的point

CGPoint viewP = [self convertPoint:point toView:view];

// 判断转换后的点是否在子View之内

if ([view pointInside:viewP withEvent:event]) {

return view;

}

}

return [super hitTest:point withEvent:event];

}


userInteractionEnabled = NO


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

// 1.自己先处理事件...

NSLog(@"do somthing...");

// 2.再调用系统的默认做法,再把事件交给上一个响应者处理

[super touchesBegan:touches withEvent:event];

}

One More Thing

当一个触摸事件发生后首先是由IOKit.framework 生成一个 IOHIDEvent 事件并由 SpringBoard 接收,然后SpringBoard会通过match port将事件转发给我们是App进程,然后触发App注册在RunLoop中的Source1来处理事件,Source1会触发__IOHIDEventSystemClientQueueCallback回调,回调后又会触发Source0,再后面就是UIApplication从事件队列取出事件派发

上一篇 下一篇

猜你喜欢

热点阅读