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;

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM