美文网首页iOS面试那些事iOS Developer
iOS 触摸事件与响应理解

iOS 触摸事件与响应理解

作者: Auther丶 | 来源:发表于2017-04-20 19:39 被阅读55次

    参考文章:      
     iOS触摸事件的流动

    iOS触摸事件的传递与响应

    UIViewController UIApplication UIView 都继承了UIResponder ,可响应以下事件

    UIResponder内部提供了以下方法来处理事件触摸事件- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event;- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event;- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event;- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event;

    一 触摸事件的产生与传递

    找: 从父视图往子视图 倒序遍历查找最适合的responder

    1.首先判断 自己是否能接受触摸事件

    2.判断触摸点是否在自己身上

    3.子控件数组中从后往前遍历子控件,重复前面的两个步骤(所谓从后往前遍历子控件,就是首先查找子控件数组中最后一个元素,然后执行1、2步骤)

    4.view,比如叫做fitView,那么会把这个事件交给这个fitView,再遍历这个fitView的子控件,直至没有更合适的view为止。

    5.如果没有符合条件的子控件,那么就认为自己最合适处理这个事件,也就是自己是最合适的view。


    其中以下三种情况则会阻断查找,自己和自己的所有子视图都不会是那个合适的responder

    1.userInteractionEnabled = NO 

    2.alpha < 0.01 

    3.hidden = YES

    // 什么时候调用:只要事件一传递给一个控件,那么这个控件就会调用自己的这个方法// 作用:寻找并返回最合适的view// UIApplication -> [UIWindow hitTest:withEvent:]寻找最合适的view告诉系统// point:当前手指触摸的点// point:是方法调用者坐标系上的点


    - (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event{
    // 1.判断下窗口能否接收事件
    if(self.userInteractionEnabled ==NO||self.hidden ==YES||self.alpha <=0.01) return nil;
    // 2.判断下点在不在窗口上// 不在窗口上
    if([selfpointInside:point withEvent:event] ==NO) return nil;
    // 3.从后往前遍历子控件数组
    intcount = (int)self.subviews.count;for(inti = count -1; i >=0; i--)    {
    // 获取子控件
    UIView*childView =self.subviews[i];
    // 坐标系的转换,把窗口上的点转换为子控件上的点
    // 把自己控件上的点转换成子控件上的点
    CGPointchildP = [selfconvertPoint:point toView:childView];

    UIView*fitView = [childView hitTest:childP withEvent:event];
    if(fitView) {
    // 如果能找到最合适的view

    return fitView;   

     }   
     }
    // 4.没有找到更合适的view,也就是没有比自己更合适的view
    return self;   
    }

    // 作用:判断下传入过来的点在不在方法调用者的坐标系上// point:是方法调用者坐标系上的点
    //- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
    //{
    // return NO;
    //}

    触摸事件

    二 事件响应过程

    当找到这个最合适的视图,看它是否重写了touchBegan等方法或者有 UIGesture等手势。先执行重写的touchBegan方法 ( 滑动 - moved方法), 若有手势再执行手势的action,最后执行 touchCancled方法。终止。
     如果都没有,就调用默认实现 super touchXXX 将事件交给上一个响应者。

    注意VC.view 根视图的上一个响应者是 VC


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

    {//调用super 就是将事件沿着响应者链条往上传递

    [super touchesBegan:touches withEvent: event];

    }

    事件响应链

    两个关键的方法能做什么用


    (1).在自定义的父类中写 如下代码 可以在这个父类View  frame 内所有的触摸事件执行前 先执行xxxx ,并且不打断 子控件 的交互


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

        [self xxxx];

        [super  hitTest:point withEvent:event ];

    }

    (2).touch等方法中先执行xxx,然后再将事件传递给 上一个响应者 如果上一个响应者即写了 touchBegan 又加了手势, 那么会再执行完上一个响应者的touchBegan后,执行手势的action,然后执行上一个响应者的 touchCancled,再执行自己的touchCancled

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

    {

       [self xxx];

        [supertouchesBegan:toucheswithEvent:event];

    }

    未完待续: 手势理解明天再写。

    相关文章

      网友评论

      本文标题:iOS 触摸事件与响应理解

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