美文网首页
iOS-hitTest方法的底层实现(超出父View响应事件、扩

iOS-hitTest方法的底层实现(超出父View响应事件、扩

作者: F麦子 | 来源:发表于2021-08-20 20:10 被阅读0次

    1.原理底层伪代码

     2:hitTest 方法的练习1:

    业务逻辑:

    底部一个按钮, 按钮的上面有一个View,遮挡在按钮的上面.

    点击View时, View接收事件,当发现点击的点在按钮的位置时, 让底部的按钮处理事件.

    实现思路:

    实现View的touchBegain方法,先坚听UIView的点击.

    并去实现UIView的HitTest方法, 在hitTest方法当中通过把当前点转换成按钮所在的坐标系

     CGPoint btnP = [self convertPoint:point toView:self.btn];

     转换过后查看当前点在不在按钮上,如果在按钮上,就直接返回按钮.

     如果有在按钮上,保持系统默认做法.

        实现代码:

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

        判断当前点在不在按钮上.

        把当前点转换成按钮所在的坐标系

        CGPoint btnP = [self convertPoint:point toView:self.btn];

        if ([self.btn pointInside:btnP withEvent:event]) {

            return self.btn;

        }else{

          return [super hitTest:point withEvent:event];

        }

    }

    注意:在storyBoard中定义了view和按钮,view自定义可以拖线到自定义的view中,前提是得进行类的关联,但是button不能拖入,因为button不属于view的子控件,解决:可以在view中属性定义IBOutlet,在拖线到storyBoard中的按钮,这样就在view中拿到了不属于view的button

    2:hitTest练习2

    业务逻辑:

    按钮可以随着⼿手指拖动⽽而拖动.拖动过程当中,按钮当中的⼦子控件也跟着拖动. 让超过按钮的⼦子控件也能够响应事件,⼀一般情况下,当⼀一个控件超过他的⽗父控件的时候,是不能 够接收事件的.

    现在要做的事情就让超过⽗父控件的按钮也能够响应事件.

    一般情况下,当⼀一个控件超过他的⽗父控件的时候,是不能 够接收事件的.原因是:

    1:当产生触摸事件后,系统会将触摸事件发送到由UIApplication管理的事件队列中,UIApplication会将队列中最前端的事件取出来交给keywindow去处理,主窗口keywindow会1:查看自身能不能接受触摸事件 

    2:触摸点是不是在自身上 

     3:若是前两个条件都满足则其会遍历自身的子控件,且是从后到前遍历,也就是从子控件数组的最后一个控件开始遍历,再执行前两个步骤,若是不在,则遍历下一个子控件,若是一直没找到,则自己就是最合适处理事件的view,若在,则继续重复前两个步骤,直到找到最合适的view。

    当点击按钮的时候window将事件传递到白色view,白色view从后往前遍历子控件,先遍历蓝色的button,再遍历点击对话框,找到适合处理事件的view。当子控件超出父控件的范围后,点击子控件时不会响应事件,原因是:当遍历到父控件点击对话框时,触摸点不再其身上,则其就不会响应事件

    实现思路:

    第一步,先办到让按钮能够跟随着⼿手指移动⽽而移动. 实现按钮的touchesMoved⽅方法,在touchesMoved⽅方法当中,获得当前⼿手指所在的点.以前上一 个点.一个手指对应一个UITouch对象,一个手指取出UITouch,anyobject,若是多根手指则会touch.allobjects获取所有的UITouch对象,分别计算X轴的偏移量以及Y轴的偏移量. 然后修改当前按钮的transform让按钮办到能够跟随着⼿手指移动⽽而移动(累加形变).

    第二步,

    1: 实现按钮的hitTest⽅法. 在该方法当中去判断当前的点在不在按钮的⼦控件上. 如果在按钮的⼦控件上.就返回按钮的子控件,如果不在的话, 就保持系统的默认做法.一般在父类中重写hitTest方法,修改返回最合适的view

     2:self.chatBtn.btn定义为弱引用, self.chatBtn.btn = btn赋值指针地址,弱引用指向该对象,[self.chatBtn addSubview:btn];强引用引用着btn使其不被销毁,所以可以用weak

     3:事件会由白色view传递到其子控件self.chatBtn上,所以在self.chatBtn的类里重写hitTest方法,修改返回的view

    相关文章

      网友评论

          本文标题:iOS-hitTest方法的底层实现(超出父View响应事件、扩

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