iOS控件超出父控件范围如何与用户交互

功能需求:当button超出父控件frame的时候如何与用户交互
如图:btn1和btn2都是蓝色View的子控件,但是他们超出了蓝色View的frame
如果不做任何处理,点击btn,btn是不能与用户交互的
Btn3在父控件范围内,可以与用户交互
这里是源码

iOS控件超出父控件范围如何与用户交互_第1张图片
Demo图.png

响应者链条:(系统如何找到最合适的View来响应用户的交互)

当用户点击屏幕
产生一个点击事件交给UIAppliction
UIAppliction交给UIWiondw
UIWiondw问控制器View:触点在不在你身上?
在,则把点击事件交给控制器View
控制器View问自己的子控件(从最后添加的,也就是最上层的view开始询问):触点在不在你身上?
在,则把事件传递给这个子View
不在,则继续问下一个子控件
如果找到了合适的子控件,则把事件传递给子控件(子控件继续询问自己的子控件来查找更合适的view)
如果没有找到,则自己处理事件

例如点击了Btn3:
UIWiondw问控制器的白色View触点在你身上吗?
在,事件传递到控制器的白色View上
白色Viwe问蓝色Viwe,触点在你身上吗?
在,事件传递到蓝色View
然后蓝色View问Btn3,触点在你身上吗?
在,则事件交给Btn3
Btn3已经没有子控件(也就是没有更合适的View了)
Btn3处理了点击事件

又例如点击了Btn1
UIWiondw问控制器的白色View触点在你身上吗?
在,事件传递到控制器的白色View上
白色Viwe问蓝色Viwe,触点在你身上吗?
不在,则白色View处理点击事件(因为白色View已经没有其他子控件可以询问,Btn1是蓝色Viwe的子控件)
所以Btn1不能响应用户的交互

如何让Btn1与用户交互

在询问子View的时候,系统是通过这个方法来寻找最合适的View:

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

所以我们可以重写控制器View的这个方法,来按照自己制定的规则来寻找最合适的View:

-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
    //当前触点坐标系是控制器的view
    //转换成btn1的坐标系
    CGPoint btnP = [self convertPoint:point toView:self.btn1];
    if ([self.btn1pointInside:btnP withEvent:event]) {//判断点击点是否在btn1上
        //如果点击点在btn1上 那么就让btn1来处理事件
        return self.btn1;
    }else{
        //如果不在btn1上 就按照系统默认做法  寻找合适的view来处理事件
        return [super hitTest:point withEvent:event]
    }
}

这样的话,当触点在Btn1上的时候,这个方法就会返回Btn1
那么系统就会把Btn1当做最合适的View来处理事件

感谢阅读
你的支持是我写作的唯一动力

关注我的文章微信公众号, 随时与你分享我的文章

iOS控件超出父控件范围如何与用户交互_第2张图片
扫码关注我.jpg

你可能感兴趣的:(iOS控件超出父控件范围如何与用户交互)