zoukankan      html  css  js  c++  java
  • UIView 坐标转换

    例子1

    Controllerview中有一个tableViewtableViewcell上有一个button,现在需要将buttonframe转为在Controllerview中的frame,怎么实现呢?

    CGRect rect = [self.view convertRect:_button.frame fromView:_button.superview];
    CGRect rect
    = [_button.superview convertRect:_button.frame toView:self.view];

    注意1.

    button的frame是相对于其superview来确定的,frame确定了button在其superview的位置和大小

    注意2.

    现在转换后,我们肉眼观察到的,所有屏幕上的控件的布局并不会改变,但是此时以上两个方法返回的frame代表着,button在self.view上的大小和位置

    注意3.

    这里应该使用的是_button.frame而不能是_button.bounds

    注意4.

    这里2个方法是可逆的,2个方法的区别就是消息的接收者和view参数颠倒

    注意5.

    这里_button虽然是在tableView上的,但是不能写toView的消息接收者不能是tableView,因为_button的superview并不是tableView

    注意6.

    注意理解消息的接收者,即第一行代码的self.view和第二行代码的_button.superview

    一般来说,toView方法中,消息的接收者为被转换的frame所在的控件的superview;fromView方法中,消息的接收者为即将转到的目标view

    注意7.

    涉及的所有view的UIWindow必须是同一个对象!否则转换失败

    例子2

    现在需要将一个触摸事件的点screenPoint(触摸事件的点的坐标系是相对于当前的屏幕——UIWindow),转化为屏幕里某个tableView上的点。即我想知道,我现在触摸的屏幕位置,是在这个tableView的什么位置上

    CGPoint tablePT = [_tableView convertPoint:screenPoint fromView:nil];

    注意1.

    当参数view为nil的时候,系统会自动帮你转换为当前窗口的基本坐标系(即view参数为整个屏幕,原点为(0,0),宽高是屏幕的宽高)

    注意2.

    当view不为nil的时候,消息的接收者和参数view都必须是在同一个UIWindow对象里

    If view is nil, this method instead converts to window base coordinates. Otherwise, both view and the receiver must belong to the same UIWindow object.

    例子3

    responseDragbackAtScreenPoint方法用于判断是否响应横滑返回消息,screenPoint是触摸事件的点

    现在tableView上的cell中有一个横滑列表(UIScrollView),现在需要判断触摸点是否在UIScrollView的区域上,再根据其他条件判断是否需要横滑返回

    - (BOOL)responseDragbackAtScreenPoint:(CGPoint)screenPoint
    {
        //将当前触摸点转化为tableView上的点
        CGPoint tablePT = [tableView convertPoint:screenPoint fromView:nil];
        //根据tableView上的点定位到当前点的IndexPath
        NSIndexPath *pathIndex = [tableView indexPathForRowAtPoint:tablePT];
        //根据IndexPath找到当前触摸位置的cell
        UITableViewCell *cell = [tableView cellForRowAtIndexPath:pathIndex];
        
        //遍历该cell上的所有subView
        NSArray *subViews = [cell.contentView subviews];
        for (UIView *itemView in subViews)
        {
            //找打当前cell上的UIScrollView,目前业务上只有1个
            if ([itemView isKindOfClass:[UIScrollView class]])
            {
                UIScrollView *itemScrollView = (UIScrollView *)itemView;
                //将当前的scrollView的frame转为相对于整个屏幕上的frame
                CGRect rc = [itemScrollView.superview convertRect:itemScrollView.frame toView:nil];
                //因为screenPoint和rc是同一个坐标系下的,所以可以用来判断screenPoint是否在rc的区域内
                //1.当scrollView的cell超过屏幕的时候 2.当触摸点在scrollView的区域上的时候 3.当不是以下情况:scrollView还未被滑动的时候手指在上面向右滑 1.2.3都满足的情况下才不响应横滑返回
                if (itemScrollView.contentSize.width > itemScrollView.width &&
                    CGRectContainsPoint(rc, screenPoint) &&
                    !(itemScrollView.contentOffset.x == -itemScrollView.contentInset.left))
                    return NO;
            }
        }
        return YES;
    }
    View Code

     

    汇总

    iOS中,常用的坐标转换和frame转换如下:

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

      

  • 相关阅读:
    学习windows的半天+学习Git分布式系统的半天
    输出从1加到100的结果、打印100以内的质数、计算一个文件中的每个英文单词出现的次数
    Linux操作系统--初级--进程管理的命令
    Linux操作系统--初级--防火墙
    Linux操作系统--初级--dns服务
    Linux操作系统--初级--网络安全基础
    Linux操作系统--初级--进程管理
    Linux操作系统--初级--Linux网络
    Linux操作系统--初级--Linux磁盘管理
    Linux操作系统--初级--Linux的用户与用户组(权限管理)
  • 原文地址:https://www.cnblogs.com/chenyg32/p/4800420.html
Copyright © 2011-2022 走看看