zoukankan      html  css  js  c++  java
  • iOS--坐标转换convertPoint

    前言

    在开发的过程中,不免会遇到子控件超过父视图的情况。都知道,超出父视图的部分是不能响应点击事件,但是总有些情况需要我们让超出的部分响应点击事件,那么convertPoint就可以大显身手了。小白可参考,大神请指点。

    先说解决方法

    在父视图重写下面的方法

    //重写该方法后可以让超出父视图范围的子视图响应事件
    - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
        UIView *view = [super hitTest:point withEvent:event];
        if (view == nil) {
            for (UIView *subView in self.subviews) {
                CGPoint convertPoint = [subView convertPoint:point fromView:self];
                if (CGRectContainsPoint(subView.bounds, convertPoint)) {
                    view = subView;
                }
            }
        }
        return view;
    }
    

    为什么上面的方法能解决问题呢

    这和iOS的事件分发机制 hit-Testing有关,简单的说,hit-Testing的作用就是找出你每次触摸屏幕,点到的究竟是哪个view。

    如图:

    参考图

    当用户去点击View-C的时候,hit-Testing实际上是这样检测的:
    • 首先,视图会先从View-A开始检查,发现触摸点在View-A,所以检查View-A的子视图View-B
    • 发现触摸点在View-B内,,看看View-B内的子视图View-C
    • 发现触摸点在View-C内,但View-C没有子视图了,所以View-C是此次触摸事件的hit-TestView了。

    UIView中其实提供了两个方法来确定hit-TestView:

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

    注意:其实在每次递归去调用hitTest:(CGPoint)point withEvent:(UIEvent *)event之前,都会调用pointInside:withEvent:来确定该触摸点是否在该View内。

    其实有关convertPoint常用的方法还有几个

    • 转换像素点
    // 将像素point由point所在视图转换到目标视图view中,返回在目标视图view中的像素值
    - (CGPoint)convertPoint:(CGPoint)point toView:(UIView *)view;
    
    // 将像素point从view中转换到当前视图中,返回在当前视图中的像素值
    - (CGPoint)convertPoint:(CGPoint)point fromView:(UIView *)view;
    
    • 转换Rect
    // 将rect由rect所在视图转换到目标视图view中,返回在目标视图view中的rect
    - (CGRect)convertRect:(CGRect)rect toView:(UIView *)view;
    
    // 将rect从view中转换到当前视图中,返回在当前视图中的rect
    - (CGRect)convertRect:(CGRect)rect fromView:(UIView *)view;
    

    例把UITableViewCell中的subview(btn)的frame转换到 controllerA中

    // controllerA 中有一个UITableView, UITableView里有多行UITableVieCell,cell上放有一个button
    // 在controllerA中实现:
    CGRect rc = [cell convertRect:cell.btn.frame toView:self.view];
    或者
    CGRect rc = [self.view convertRect:cell.btn.frame fromView:cell];
    // 此rc为btn在controllerA中的rect
    

    当已知btn时:

    CGRect rc = [btn.superview convertRect:btn.frame toView:self.view];
    或者
    CGRect rc = [self.view convertRect:btn.frame fromView:btn.superview];
    

    后记

    目前只是简单的使用,还没有深入了解,以后有时间再更新。有问题请留言,共同学习,一起进步。
    感谢 -- 任性的小丸子
    感谢 -- zhanglizhi111



    作者:MQ_Twist
    链接:https://www.jianshu.com/p/cc7e74d5b8f7
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    HDU 1573: X问题
    HDU 1370: Biorhythms
    Break Number --AtCoder
    Cat Snuke and a Voyage --AtCoder
    Fennec VS. Snuke --AtCoder
    Splitting Pile --AtCoder
    Sharing Cookies --AtCoder
    GLB串
    派(Dispatch)
    你知道那棵杨树底下有什么吗
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/13212671.html
Copyright © 2011-2022 走看看