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。

如图:

iOS--坐标转换convertPoint
参考图

当用户去点击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
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

iOS--坐标转换convertPoint

上一篇:uni-app中子页面向父页面传值


下一篇:#2 bootstrap安装与引入 (bootstrap4系列)