美文网首页
iOS 响应链相关小结

iOS 响应链相关小结

作者: sooon77 | 来源:发表于2018-12-13 10:12 被阅读0次

    传递链

    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。

    应用

    • 子View超出superView后,仍然响应点击,相关解决方案
    
    - (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];
    
    }
    
    
    • 子View不响应,直接透传给superView
    
    userInteractionEnabled = NO
    
    
    • 子View响应后,superView仍然响应
    
    - (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从事件队列取出事件派发

    相关文章

      网友评论

          本文标题:iOS 响应链相关小结

          本文链接:https://www.haomeiwen.com/subject/hwlvhqtx.html